damonkohler / sl4a

SL4A brings scripting languages to Android by allowing you to edit and execute scripts and interactive interpreters directly on the Android device.
Apache License 2.0
2.42k stars 804 forks source link

Allow running scripts as root on rooted phones #281

Open damonkohler opened 9 years ago

damonkohler commented 9 years ago

From @GoogleCodeExporter on May 31, 2015 11:24

Should be useful for people that use rooted phones.

Original issue reported on code.google.com by damonkoh...@gmail.com on 27 Jan 2010 at 11:59

Copied from original issue: damonkohler/android-scripting#184

damonkohler commented 9 years ago

From @GoogleCodeExporter on May 31, 2015 11:24

This would be fantastic.  I have a particular use for this now, an ssh client 
that I 
installed can't work in ASE (in a shell script) because the uid of the 
application 
isn't in /etc/passwd.  There are no such problems when running outsied of ASE 
as root.

Original comment by mindsoc...@gmail.com on 4 Feb 2010 at 10:54

damonkohler commented 9 years ago

From @GoogleCodeExporter on May 31, 2015 11:24

Here is a project that would benefit from this:
http://www.instructables.com/id/Android-G1-Serial-To-Arduino/

It uses an Android phone to connect to an Arduino board over serial. The script 
must 
currently be launched from the terminal under su.

Original comment by rhickman on 13 Feb 2010 at 4:50

damonkohler commented 9 years ago

From @GoogleCodeExporter on May 31, 2015 11:24

Is "su -c 'command goes here'" not working?

Original comment by iconra...@gmail.com on 22 Feb 2010 at 3:55

damonkohler commented 9 years ago

From @GoogleCodeExporter on May 31, 2015 11:24

I think the point is to make it easier to launch scripts as root from within 
ASE. Just 
for the sake of convenience.

Original comment by damonkoh...@gmail.com on 22 Feb 2010 at 9:35

damonkohler commented 9 years ago

From @GoogleCodeExporter on May 31, 2015 11:24

Original comment by damonkoh...@gmail.com on 2 May 2010 at 9:48

damonkohler commented 9 years ago

From @GoogleCodeExporter on May 31, 2015 11:24

This should be doable. When ASE starts a proc for a script, that proc needs to 
get the su 
runtime and write everything else after that to to su's stdin.

This could be an option or just coded to "detect" the su binary and then 
proceed 
accordingly.

I'll try and come up with some source in my clone to test this out.

PS: All my attempts at running ase as root with external code have failed.

Original comment by mr.mcfiddles on 6 May 2010 at 6:39

damonkohler commented 9 years ago

From @GoogleCodeExporter on May 31, 2015 11:24

Can't something like this be incorporated into the code?

http://code.google.com/p/gscript-android/source/browse/trunk/GScript/src/nl/rogr
o/GScript/GScriptExec.java

If ASE has root access it'll become one of the most powerful tools available I
believe, I really wish we could get it.

Original comment by CJE...@gmail.com on 14 May 2010 at 1:32

damonkohler commented 9 years ago

From @GoogleCodeExporter on May 31, 2015 11:24

I have been trying to use a modded version of SuperUser.java pulled from the 
DroidMod git 
repo. The problem, for me at least, is trying to figure out what proc to wrap 
the 
SuperUser.oneShot() method around.  ASE doesn't create an initial proc from 
which 
everything else is run. Its really dynamic, which is a good thing, but getting 
everything after 
a script is run to be passed to the su binary's stdin is really tricky.

So far I have managed to compile a version of ASE that imports SuperUser.java 
into ASE's 
Exec.java, but all attemps at integrating SuperUser.oneShot() have crashed 
Android.

Maybe we could just use a .bashrc file that makes every terminal a root 
terminal??

Original comment by mr.mcfiddles on 14 May 2010 at 6:40

damonkohler commented 9 years ago

From @GoogleCodeExporter on May 31, 2015 11:24

After many hours toiling with the source, I had a brilliant idea.  Although it
doesn't give ASE scripts root access, you can perform root commands.  It uses 
the
functionality of 'su -c <command>'.  When calling su -c the user has to allow 
for
each command called.  Using the following script, with the syntax 'sush 
"<command1>"
"<command2>" ... "<commandN>"' you can now use root-based commands in ASE 
scripts! =)

I would put sush in /system/xbin, I will not explain how to do this.

Example in Lua (shows usage and limitations):

[WILL WORK]
require "android"
os.execute('sush "mount -o remount,rw -t yaffs2 /dev/block/mtdblock4 /system" 
"cp
/system/build.prop /system/build.prop.old"')

[WILL NOT WORK]
require "android"
os.execute('sush "mount -o remount,rw -t yaffs2 /dev/block/mtdblock4 /system"')
os.execute("cp /system/build.prop /system/build.prop.old")

Original comment by CJE...@gmail.com on 15 May 2010 at 7:48

Attachments:

damonkohler commented 9 years ago

From @GoogleCodeExporter on May 31, 2015 11:24

this is a horribly insecure way to do it, but

#!/sytem/bin/sh
echo "#!/sytem/bin/sh
mount -o remount,rw -t yaffs2 /dev/block/mtdblock4 /system
cp /system/build.prop /system/build.prop.old" > /sqlite_stmt_journals/foo.sh
su -c "sh /sqlite_stmt_journals/foo.sh"
rm /sqlite_stmt_journals/foo.sh

nasty thing about it is if the user ticks always allow ( on su perms ) ase will 
always be able to execute that script as root!!
should at least check that the file did get created as we expected..

Original comment by firer4t@googlemail.com on 20 May 2010 at 5:06

damonkohler commented 9 years ago

From @GoogleCodeExporter on May 31, 2015 11:24

[deleted comment]
damonkohler commented 9 years ago

From @GoogleCodeExporter on May 31, 2015 11:24

[deleted comment]
damonkohler commented 9 years ago

From @GoogleCodeExporter on May 31, 2015 11:24

As horrible as the above, but atleast does not require an echo to a su - 
runnable file (all kinds of problems with escaping for advanced scripts) - 
basically calls the script itself with su if not root:

#!/system/bin/sh
if [ "$(id -u)" == "0" ]; then
  echo -e "\n\n"
  echo -e "Mounting /system RW...\n"
  mount -o remount,rw -t yaffs2 /dev/block/mtdblock3 /system
else
  echo -e "Getting root priveleges\n"
  su<$0
fi

Original comment by girts.ni...@gmail.com on 4 Jul 2010 at 2:18

damonkohler commented 9 years ago

From @GoogleCodeExporter on May 31, 2015 11:24

CEnnis:
thanks for the workaround, sush is working great with my bash scripts!

Original comment by TheW...@gmail.com on 5 Sep 2010 at 12:35

damonkohler commented 9 years ago

From @GoogleCodeExporter on May 31, 2015 11:24

Given
$ cat /sdcard/sl4a/scripts/my_uid.py
import os
print "UID=", os.getuid()
$ cat /sdcard/sl4a/scripts/execsu.py
import os
import sys

pythonexe = os.path.join(sys.prefix, "bin/python")
print "before", os.getuid()
os.system("%s -c 'import os; print os.getuid()'" % pythonexe)
os.execv("/system/xbin/su", ["su", "-c", "%s /sdcard/sl4a/scripts/my_uid.py" % 
pythonexe])

Runnning execsu.py from SL4A displays 
   before 10105
   10105
   UID= 0
under rooted CyanogenMod 6 (you get a prompt from the su-manager before the 
UID=0.)

I used os.execv directly because "import subprocess" fails to import select, 
and I suppose using os.execvp would have simplified it a little as well - to 
use this, all you need is one "invoke su" wrapper, which strips down to

import os, sys
pythonexe = os.path.join(sys.prefix, "bin/python")
os.execv("/system/xbin/su", ["su", "-c", "%s 
/sdcard/sl4a/scripts/my_program.py" % pythonexe])

and then my_program.py itself is whatever you want to run as root.  (I dug into 
this because I actually want a helper to turn device_provisioned back on in 
settings.db...)

Original comment by eic...@gmail.com on 2 Dec 2010 at 8:42

damonkohler commented 9 years ago

From @GoogleCodeExporter on May 31, 2015 11:24

I can't get sush to work. I downloaded the file and copied it to /system. I 
know above it recommends /system/xbin, but I figured /system should work. But 
when I try and do 

os.system('sush <somecommand>') 

in a python script I get sush: permission denied

ANy ideas?

Original comment by hueth...@gmail.com on 6 Jan 2011 at 8:11

damonkohler commented 9 years ago

From @GoogleCodeExporter on May 31, 2015 11:24

permission denied might actually mean that the file is not found.  Try using 
the recommended path (/system/xbin) and see if that fixes the problem.

Original comment by brettway...@gmail.com on 1 Feb 2011 at 2:24

damonkohler commented 9 years ago

From @GoogleCodeExporter on May 31, 2015 11:24

How about something like:

if os.getuid() != 0:
   cmd="su -c `cat /proc/%s/cmdline`" % os.getpid()
   os.execute(cmd)
   sys.exit()

at the start of the code? (Python)

Original comment by pink.ban...@gmail.com on 8 Mar 2011 at 8:06

damonkohler commented 9 years ago

From @GoogleCodeExporter on May 31, 2015 11:24

I used sush posted above and created the script:

#!/system/bin/sh
sush "sh /sdcard/myscript.sh"

That worked perfectly. I can now add scripts to Tasker by linking to the above 
script to run my actual script, "myscript.sh". This of course has the drawback 
of not being secure in the least. It works for now. 

Original comment by mma...@mailinator.com on 1 Apr 2011 at 3:29

damonkohler commented 9 years ago

From @GoogleCodeExporter on May 31, 2015 11:24

@hueth...@gmail.com

if you're going to put it in /system then you'll have to do /system/sush, which 
is annoying, if /system/xbin isn't there, put it in /system/bin.

Original comment by CJE...@gmail.com on 6 Jun 2011 at 1:47

damonkohler commented 9 years ago

From @GoogleCodeExporter on May 31, 2015 11:24

Hi,

if i follow this example:

$ cat /sdcard/sl4a/scripts/my_uid.py
import os
print "UID=", os.getuid()
$ cat /sdcard/sl4a/scripts/execsu.py
import os
import sys

pythonexe = os.path.join(sys.prefix, "bin/python")
print "before", os.getuid()
os.system("%s -c 'import os; print os.getuid()'" % pythonexe)
os.execv("/system/xbin/su", ["su", "-c", "%s /sdcard/sl4a/scripts/my_uid.py" % 
pythonexe])

I end up with message: could not load needed library 'libphython2.6.so' ...

I tried setting PYTHONHOME, PYTHONPATH, PATH and LD_LIBRARY_PATH in a sh script 
and call python from within, but the variables are not exported when started 
with su -c.

Is there a way to set these variables permanently, so that they are recognized 
from Shell scripts and python can be started as both root and non root?

Original comment by poetter...@googlemail.com on 22 Aug 2011 at 2:28

damonkohler commented 9 years ago

From @GoogleCodeExporter on May 31, 2015 11:24

Here's a script I put at /bin/python that works for me to start the interpreter 
from the command line::

  #!/bin/sh
  export PYTHONPATH=/sdcard/com.googlecode.pythonforandroid/extras/python:/sdcard/com.googlecode.pythonforandroid/files/python/lib/python26.zip
  export PYTHONHOME=/data/data/com.googlecode.pythonforandroid/files/python/ 
  export LD_LIBRARY_PATH=/data/data/com.googlecode.pythonforandroid/files/python/lib/
  exec /data/data/com.googlecode.pythonforandroid/files/python/bin/python "$@"

With this `su -c "python script.py"` works fine.

Original comment by albertas...@gmail.com on 3 Oct 2011 at 8:58

damonkohler commented 9 years ago

From @GoogleCodeExporter on May 31, 2015 11:24

Note: over-writing the value of LD_LIBRARY_PATH _will_ cause Android system 
tools to stop working (in the active session). I was just trying to launch SL4A 
in server mode from ConnectBot using the am tool, but it kept failing with 
linker errors.

Change the above to "export 
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/data/data/com.googlecode.pythonforandroid/file
s/python/lib/" and it will work for both Python and any subsequent commands.

Original comment by kitsu...@gmail.com on 12 Jan 2012 at 11:21

damonkohler commented 9 years ago

From @GoogleCodeExporter on May 31, 2015 11:24

Unfortunately it is not possible to use sush like this:

sush "command 1"
"command 2"
"command 3"

It is neccessary to write it in one line, what is with Android phones a bit 
difficult to view, write and read.

Original comment by francwal...@gmail.com on 29 Mar 2012 at 8:33

damonkohler commented 9 years ago

From @GoogleCodeExporter on May 31, 2015 11:24

The whole “su” thing makes only sense if not everything can get root 
rights! sush fails horribly here.

To make it right:
1)
$ su -c '/absolute/path/to/command with as much arguments you want'

Always call your command with absolute path, so the user can check if it trusts 
it. As $PATH is not filtered by su, relative commands should be rejected by su 
(but it fails here).

2)
Does Android’s shared library loader fail on ignoring LD_LIBRARY_PATH on suid 
programs like su? BUG! Or does it just not remove it from the environment?

3)
Assuming we want to run a couple of python scripts as root, the user trusts 
those scripts. For two reasons I want to split my script in two: a generic 
python wrapper and the real script. a) the python binary from sl4a doesn’t 
run without setup and b) the minimum setup necessary should not be repeated in 
all scripts. The call will look like

su -c '/path/to/pythonwrapper /script/to/run/as/root'

This runs "/the/shell/of/root -c '/path/to/pythonwrapper 
/script/to/run/as/root'".

I can’t do much for the root-shell, beyond hoping that Android removes 
LD_LIBRARY_PATH from environment in the future, or su starts cleaning it (in 
Cyanogenmod 7.1 it does not). The shell is hopefully too simple to load 
profiles or anything else.

4)
The pythonwrapper runs from a possibly hostile environment, as root.
Lets implement it in shell. The first line should be

#!/the/shell/of/root
# which for me is /system/bin/sh

If this is a security risk, I was already fucked in 3). The rest is:

# clean the environment of all PYTHON*
unset "${!PYTHON@}"  # doesn’t work in my crappy Android shell

dataPath=/data/data/com.googlecode.pythonforandroid/files/python
LD_LIBRARY_PATH=/vendor/lib:/system/lib:$dataPath/lib \
PYTHONHOME=$dataPath \
PYTHONPATH=/vendor/lib:/system/lib:/sdcard/com.googlecode.pythonforandroid/extra
s/python \
exec "$dataPath"/bin/python "$@"

Assuming that simple shell doesn’t read aliases and functions from the 
environment, because “exec” may be one.

5) now it is on the “trusted script” to clean up from a possible attacker. 
Emptying the environment may be one thing to do.

Original comment by Darten.b...@gmail.com on 5 Jun 2012 at 12:24

damonkohler commented 9 years ago

From @GoogleCodeExporter on May 31, 2015 11:24

I've been after this issue for a few days now and i've tried most of the above 
fixs, but they didn't work.  The problem with using su is that only the root 
(uid=0) and shell (uid=2000) users are allowed to use it.  All other users, in 
my cases my application, receive "su: uid XXXX not allowed to su".  This is 
done for security reasons, no one wants a rogue application with root 
permissions. O wait we do... So my work around was to recompile su binary 
without this nasty security catch, called it suu (substitute user 
unrestricted), pushed it into /system/xbin, gave it permissions (chmod 6755 
suu), and use it instead of su.  So far its been working pretty well.  I'm 
awhere this is a massive security hole, but any method of giving an application 
root rights is a security hole.  Hope that helps.

Original comment by MQue...@gmail.com on 9 Jul 2012 at 1:41

Attachments:

damonkohler commented 9 years ago

From @GoogleCodeExporter on May 31, 2015 11:24

No, _giving_ a specific application I know root-rights is not a security hole 
per se. – But having a way for all application to _take_ root-rights is.

My su is not restricted to specific users, everyone can call it and a window 
pops up on the phone asking if I want to permit or deny this.

Original comment by Darten.b...@gmail.com on 9 Jul 2012 at 4:47

ghost commented 7 years ago

it ain't that hard realy, just put this above youre script:

import os if os.getuid() != 0: os.system('su sh data/data/org.qpython.qpy/files/bin/qpython.sh ' + file)

ghost commented 7 years ago

file == 'file'

ghost commented 7 years ago

i am sory but github doesn't allow me to show it correctly, file must be youre path and scriptname

Lukasz9393 commented 1 year ago

From @GoogleCodeExporter on May 31, 2015 11:24

Should be useful for people that use rooted phones.

Original issue reported on code.google.com by damonkoh...@gmail.com on 27 Jan 2010 at 11:59

Copied from original issue: damonkohler/android-scripting#184