问题:user版本增加su 指令以后,允许切换root用户,但是,root用户默认没有设置密码,这样访问不安全。
需要增加root用户密码。
一、Linux账户管理
1.1 文件和权限
Linux一切皆文件。文件和目录都有相应的权限,权限定义的基本格式:
文件类型 所有者权限 用户组权限 其他用户权限
drwxr-xr-x 3 root root 4096 Aug 17 14:54 toolchain
drwxr-xr-x 19 root root 4096 Aug 17 14:54 tools
-rw-r--r-- 1 root root 21089672 Aug 18 16:06 u28081802.log
drwxr-xr-x toolchain 文件类型是d (文件夹) 所有者权限 rwx: 可读(r)可写(w)可执行(x),用户组权限r-x:
可读(r)可执行(x)。文件所有者是root, 用户组是 user。更加详情内容可以参考:
一文带你学习Linux 中的文件权限概念和相关命令 - 知乎 (zhihu.com)
1.2 Linux账户系统
账号用户管理登录用户,实现访问控制。
1.2.1 id命令
id命令用于查看用户和用户所在的组信息。
安卓系统查看系统用户信息:
lahaina:/ # id
uid=0(root) gid=0(root) groups=0(root),1004(input),1007(log),1011(adb),1015(sdcard_rw),1028(sdcard_r),1078(ext_data_rw),
1079(ext_obb_rw),3001(net_bt_admin),3002(net_bt),3003(inet),3006(net_bw_stats),3009(readproc),3011(uhid) context=u:r:su:
s0
lahaina:/ # id root
uid=0(root) gid=0(root) groups=0(root) context=u:r:su:s0
lahaina:/ #
root用户uid=0, 组id=0, 所在的组root, SELinux策略上下文: u:r:su:s0
已经内置了root用户。还有其他的系统用户,shell, adb等。
lahaina:/ # id shell
uid=2000(shell) gid=2000(shell) groups=2000(shell) context=u:r:su:s0
lahaina:/ #
1.2.2 useradd命令
lahaina:/ # id root
uid=0(root) gid=0(root) groups=0(root) context=u:r:su:s0
useradd 命令用于创建新的用户
命令格式:useradd [-选项] 用户名
常用选项:
-u 指定用户UID,root用户的uid=0
-d 指定用户家目录,一般用户目录, /home/[用户名], 可以通过cd ~到当前用户的家目录
-c 用户描述信息
-g 指定用户基本组, 用户组信息,root的用户组
-G 指定用户附加组
-s 指定用户的shell
#创建用户指定用户UID、描述信息、附加组
[root@localhost ~]# useradd -u 1600 -c yunwei -G test xiaozhang
[root@localhost ~]# id xiaozhang
uid=1600(xiaozhang) gid=1600(xiaozhang) 组=1600(xiaozhang),1401(test)#/sbin/nologin :禁止用户登录系统
[root@localhost ~]# useradd -u 1800 -c test -s /sbin/nologin user8
user8:x:1800:1800:test:/home/user8:/sbin/nologin
更多信息请参考博文:
https://zhuanlan.zhihu.com/p/561408502
查看用户家目录
root@ubuntu:/etc/skel# cd ~
root@ubuntu:~# pwd
/root
例如创建一个用户 test, 用户uid=4000, 组 test。
注意:如果用户组不存在,请先创建用户组
root@ubuntu:~# groupadd -g 4000 test
root@ubuntu:~# useradd -u 4000 -g test test
root@ubuntu:~# id
uid=0(root) gid=0(root) groups=0(root)
用户创建以后,使用id查看不存在,因为id默认只能查看系统用户。
id test能看到用户test信息。
root@ubuntu:~# id test
uid=4000(test) gid=4000(test) groups=4000(test)
1.2.3 groupadd命令
groupadd [-g gid [-o]] [-r] [-f] 组名
-g gid group’s ID 值 .除非使用 -o,
-o--non-unique 参数不然该值必须是唯一, 不可相同.数值不可为负。预设为最小不得小于500而逐次增加。 0~999 传统上是保留给系统账号使用。
-r,--system 此 参数是用来建立系统账号。的 UID 会比定义在系统档上/etc/login.defs. 的 UID_MIN 来的小.注意 useradd 此法所建立的账号不会建立使用者目录,也不会在乎纪录在 /etc/login.defs. 的定义值 . 如果你想要有使用者目录须额外指定。 -m 参数来建立系统账号。 这是 RED HAT 额外增设的选项。它会自动帮你选定一个小于999 的 gif 不需要 再加上 -g 参数。这是RED HAT 额外增设的选项。
-f,--force 新增一个已经存在的群组账号,系统会出现错误讯息然后结束groupadd .如果是这样的情况,不会新增这个群组(如果 是这个情况下,系统不会再新增一次)也可同时加上 -g,--gid GID选项当你加上一个gid,此时 gid 就不用是唯一值,可不加 -o 参数,建好群组后会显结果 .
例如:创建一个分组 test, gid=4000
root@ubuntu:~# groupadd -g 4000 test
组:
基本组(初始组):一个用户只允许有一个基本组
附加组(在基本组之外组):一个用户可以允许有多个附加组
用户--->shell程序--->内核--->硬件
1.2.4 组信息保存
用户组信息保存在/etc/group文件
在Linux系统中,当您使用groupadd
命令添加新的组时,组的名称和组ID(GID)会被保存在/etc/group
文件中。这个文件是系统中所有组信息的存储库,每个组的信息都以一行的形式列出,通常遵循以下格式:
group_name:x:GID:group_members
其中:
group_name
是组的名称。x
代表组密码的占位符,实际上组密码很少使用,所以通常是一个占位符。GID
是组的唯一标识符,即组ID。group_members
是以逗号分隔的组成员用户名列表,这是可选的。
例如,如果您创建了一个名为“developers”的组并指定了GID为1002,那么/etc/group
文件中的对应行可能看起来像这样:
developers:x:1002:
此外,组的密码信息(如果设置)会被保存在/etc/gshadow
文件中,这个文件包含了更加敏感的组账户信息。
root@ubuntu:/etc# cat group | grep test
test:x:4000:
可以看到test用户组的组ID为4000.
1.2.5 用户基本信息存储
用户的基本信息存放在/etc/passwd文件,我们通过查看/etc/passwd文件内容,
可以看到当前系统所有的用户信息。
root@ubuntu:/etc/default# cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-timesync:x:100:102:systemd Time Synchronization,,,:/run/systemd:/bin/false
systemd-network:x:101:103:systemd Network Management,,,:/run/systemd/netif:/bin/false
systemd-resolve:x:102:104:systemd Resolver,,,:/run/systemd/resolve:/bin/false
syslog:x:104:108::/home/syslog:/bin/false
_apt:x:105:65534::/nonexistent:/bin/false
lxd:x:106:65534::/var/lib/lxd/:/bin/false
messagebus:x:107:111::/var/run/dbus:/bin/false
uuidd:x:108:112::/run/uuidd:/bin/false
dnsmasq:x:109:65534:dnsmasq,,,:/var/lib/misc:/bin/false
sshd:x:110:65534::/var/run/sshd:/usr/sbin/nologin
ubuntu:x:1000:1000:ubuntu,,,:/home/ubuntu:/bin/bash
systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin
tss:x:103:118:TPM software stack,,,:/var/lib/tpm:/bin/false
pollinate:x:111:1::/var/cache/pollinate:/bin/false
tcpdump:x:112:119::/nonexistent:/usr/sbin/nologin
landscape:x:113:120::/var/lib/landscape:/usr/sbin/nologin
fwupd-refresh:x:114:121:fwupd-refresh user,,,:/run/systemd:/usr/sbin/nologin
avahi:x:115:122:Avahi mDNS daemon,,,:/var/run/avahi-daemon:/usr/sbin/nologin
saned:x:116:124::/var/lib/saned:/usr/sbin/nologin
colord:x:117:125:colord colour management daemon,,,:/var/lib/colord:/usr/sbin/nologin
postfix:x:118:127::/var/spool/postfix:/usr/sbin/nologin
id:x:1001:1001::/home/id:/bin/sh
test:x:4000:4000::/home/test:/bin/sh
root@ubuntu:/etc/default#
对应,对应用户的语法格式:
用户名:密码占位符:UID:基本组GID:用户描述信息:家目录:解释器程序
root:x:0:0:root:/root:/bin/bash
#每个字段含义解释:用户名:密码占位符:UID:基本组GID:用户描述信息:家目录:解释器程序
UID:0 超级用户
UID:1-499 系统伪用户,不能登录系统并且没有家目录
UID:500-65535 普通用户
root:x:0:0:root:/root:/bin/bash
root用户,密码占位符(x),UID(0),基本组Gid(0),用户描述信息(“root”),家目录(/root),解释器程序(/bin/bash)
1.2.6 用户密码存储
用户密码信息文件/etc/shadow
root:$6$Jj2oWJVC$Q8MdYyNNzy1q1zXP8tfHAoqc8gLNvEOMAMn90zdMnGaNurZNTVTaLNDIdjLDmjcRMAIwuEJyqZKsOVY14.i2k1:19584:0:99999:7:::
daemon:*:18484:0:99999:7:::
bin:*:18484:0:99999:7:::
sys:*:18484:0:99999:7:::
sync:*:18484:0:99999:7:::
games:*:18484:0:99999:7:::
man:*:18484:0:99999:7:::
lp:*:18484:0:99999:7:::
mail:*:18484:0:99999:7:::
news:*:18484:0:99999:7:::
uucp:*:18484:0:99999:7:::
proxy:*:18484:0:99999:7:::
www-data:*:18484:0:99999:7:::
backup:*:18484:0:99999:7:::
list:*:18484:0:99999:7:::
irc:*:18484:0:99999:7:::
saned:*:19587:0:99999:7:::
colord:*:19587:0:99999:7:::
postfix:*:19587:0:99999:7:::
id:!:19688:0:99999:7:::
test:!:19688:0:99999:7:::
以冒号“:”为分界线其含义是:
daemon:*:18484:0:99999:7:::
第一段:用户名
第二段:加密密码。*:密码加密值:口令:字段存放的是加密后的用户口令,如果为空,则对应用户没有口令,登陆时不需要口令,*代表帐号被锁定,双!!表示这个密码已经过期
那么!代表什么含义呢?
在这个上下文中,!
在加密密码的位置表示该账户的密码被锁定。用户将无法使用密码登录系统。通常,这是为了防止该用户通过密码认证的方式登录系统。这可能是因为账户已经被管理员禁用,或者是一个仅用于运行服务的系统账户,不应该被用来进行交互式登录。
密码的值的前缀代表的含义:
$6$开头的,表明是用SHA-512加密的
root:$6$Jj2oWJVC$Q8MdYyNNzy1q1zXP8tfHAoqc8gLNvEOMAMn90zdMnGaNurZNTVTaLNDIdjLDmjcRMAIwuEJy
root用户有密码,且密码储存值采用SHA-512加密后,内容是“Jj2oWJVC$Q8MdYyNNzy1q1zXP8tfHAoqc8gLNvEOMAMn90zdMnGaNurZNTVTaLNDIdjLDmjcRMAIwuEJy”
$1$表明是用MD5加密的
$2$是用Blowfish加密的
$5$是用SHA-256加密的
第三段:上次密码更改日期:最后一次修改时间:从历史的某个时刻起,到用户最后一次修改口令时的天数。时间起点对不同的系统可能不一样
第四段:0:密码更改最小天数
第五段:99999:密码更改最大天数
第六段:密码警告天数:提示你用户改密码时间,7表示7天提示
第七段:密码不活动天数:超过不活动时间将冻结用户
第八段:帐户过期日期:帐号失效时间,为空
第九段:保留字段:(为空)
test账户还没有设置密码,不允许登录系统,因为为“!”表示该账户的密码被锁定,不允许通过test账号登录。
1.2.7 password命令
passwd命令修改用户密码
语法:
passwd [选项] 用户名
选项:
-S:查询用户密码的状态,也就是 /etc/shadow 文件中此用户密码的内容。仅 root 用户可用;
-l:暂时锁定用户,该选项会在 /etc/shadow 文件中指定用户的加密密码串前添加 "!",使密码失效。仅 root 用户可用;
-u:解锁用户,和 -l 选项相对应,也是只能 root 用户使用; --stdin:可以将通过管道符输出的数据作为用户的密码。主要在批量添加用户时使用;
-n 天数:设置该用户修改密码后,多长时间不能再次修改密码,也就是修改 /etc/shadow 文件中各行密码的第 4 个字段;
-x 天数:设置该用户的密码有效期,对应 /etc/shadow 文件中各行密码的第 5 个字段;
-w 天数:设置用户密码过期前的警告天数,对于 /etc/shadow 文件中各行密码的第 6 个字段;
-i 日期:设置用户密码失效日期,对应 /etc/shadow 文件中各行密码的第 7 个字段。
查看我们创建的test用户的密码情况
root@ubuntu:~# cat /etc/shadow | grep test
test:!:19688:0:99999:7:::
root@ubuntu:~#
1.2.7.1 查看密码状态
root@ubuntu:~# passwd -S test
test L 11/27/2023 0 99999 7 -1
L:密码被锁定。
"-S"选项会显示出密码状态,这里的密码修改间隔时间、密码有效期、警告时间、密码宽限时间其实分别是 /etc/shadow 文件的第四、五、六、七个字段的内容。 当然,passwd 命令是可以通过命令选项修改这几个字段的值的,
1.2.7.2 设置用户密码
设置test账户密码为test。输入密码以后,需要再次确认。
root@ubuntu:~# passwd test
New password:
Retype new password:
passwd: password updated successfully
root@ubuntu:~#
设置密码成功以后,我们再看看test的密码状态。
root@ubuntu:~# cat /etc/shadow | grep test
test:$6$o24/ASQuJAKeuREZ$C6uufWweE/SlvDK18.8Gz9WoMZ5u72Wljy/gZFOYNDxONQzGJyq5NDQbPEfBtPXDQ8cSOCvczyfvAlvBTatdY.:19689:0:99999:7:::
通过test -S test查看密码状态
root@ubuntu:~# passwd -S test
test P 11/28/2023 0 99999 7 -1
密码最近修改时间 11/28/2023, 距今密码最小更新天数为0,密码最大更改天数为9999。密码不失效(-1)。
1.2.7.3 修改密码失效天数
设置密码最大60天有效,20天更改
root@ubuntu:~# passwd -x 60 -i 20 test
passwd: password expiry information changed.
root@ubuntu:~#
root@ubuntu:~#
root@ubuntu:~# passwd -S test
test P 11/28/2023 0 60 7 20
设置以后看到密码60天有效,密码20天失效。
1.2.7.4 采用账号密码登录
我们创建了test账户,且设置了test密码,就可以使用test登录系统。root用户切换到普通用户不需要校验密码。
root@ubuntu:~# su test
$
$ su
Password:
可以看到登录成功。
1.2.7.5 验证密码哈希值
密码test的SHA-512的值是多少呢?
ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a8ff
我们回到/etc/passwd的文件,确认一下值是否是
$6$ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a8ff
对应的值为:
test:$6$o24/ASQuJAKeuREZ$C6uufWweE/SlvDK18.8Gz9WoMZ5u72Wljy/gZFOYNDxONQzGJyq5NDQbPEfBtPXDQ8cSOCvczyfvAlvBTatdY.:19689:0:60:7:20::
完全不相同?
怎么解析账号密码呢?
1.2.8 查看子用户UID
root@ubuntu:/etc# cat subuid
lxd:100000:65536
root:100000:65536
ubuntu:165536:65536
id:231072:65536
test:296608:65536
/etc/subuid保存了uid信息。
/etc/subuid
文件是在支持用户命名空间(user namespaces)的Linux系统中使用的,它保存了子用户ID(subordinate user IDs)的信息。这些子用户ID用于为特定的用户分配一组额外的用户ID,这些用户ID可以在创建用户命名空间时使用,通常与容器技术(如Docker)结合使用以提供隔离和安全性。
每行的格式通常如下:
username:lower:count
username
是系统上的用户名。lower
是分配给该用户的第一个子用户ID。count
是从lower
开始分配的用户ID数量。
例如,如果 /etc/subuid
文件包含以下内容:
linda:100000:65536
这意味着用户 linda
被分配了从 100000
开始的 65536
个连续的用户ID,范围是 100000-165535
。这些ID可以在用户命名空间中作为用户ID使用,而不会与系统上的其他用户ID冲突。
在容器化环境中,这允许容器内的进程以不同的用户ID运行,而这些用户ID在宿主机上实际上是非特权的,从而增加了安全性。这是因为即使容器内的进程以 root 用户(UID 0)运行,它在宿主机上也对应一个非特权的子用户ID,因此它不会拥有宿主机上的 root 权限。
1.2.9 查看子用户gid信息
通过/etc/subgid查看GID信息
root@ubuntu:/etc# cat subgid
lxd:100000:65536
root:100000:65536
ubuntu:165536:65536
id:231072:65536
test:296608:65536
二、密文生成和破解
2.1 密文结构
密文由 3 部分组成,以”$”分隔,第一部分为 ID,第二部分为盐值,第三部分为加密密文。
语法结构:
$6$o24/ASQuJAKeuREZ$C6uufWweE/SlvDK18.8Gz9WoMZ5u72Wljy/gZFOYNDxONQzGJyq5NDQbPEfBtPXDQ8cSOCvczyfvAlvBTatdY.
$ID$盐值$加密密文
test的ID是6,盐值是$6$o24/ASQuJAKeuREZ,
加密密文是“$6$o24/ASQuJAKeuREZ$C6uufWweE/SlvDK18.8Gz9WoMZ5u72Wljy/gZFOYNDxONQzGJyq5NDQbPEfBtPXDQ8cSOCvczyfvAlvBTatdY.”
2.1.1 ID
ID表示加密算法,取值如下:
1 MD5
5 SHA-256
6 SHA-512
2.1.2 盐值
盐值就是使用随机字符码混合密码加密算法所产生的密码,作用就是即使是同一个密码,使用同一种加密方式,所产生的密文值也不同。
2.1.3 加密密文
加密密文就是用户密码,使用盐值,对应对应的加密算法得到的加密密文。
2.2 手动生成加密密文
根据规则,我们生成测试程序 sha_manual_encrypt.py
#coding=utf-8
import crypt
passwd = "$6$o24/ASQuJAKeuREZ$C6uufWweE/SlvDK18.8Gz9WoMZ5u72Wljy/gZFOYNDxONQzGJyq5NDQbPEfBtPXDQ8cSOCvczyfvAlvBTatdY."
salt = "$6$o24/ASQuJAKeuREZ" # 盐值,包括前面的ID
cry_passwd = crypt.crypt("test",salt) # test 是明文密码,传入明文和盐值就可以生成密文了
print(cry_passwd)
print(cry_passwd == passwd)
然后执行程序,验证是否符合预期
root@ubuntu:/sandstar_aosp/projects# python sha_manual_encrypt.py
$6$o24/ASQuJAKeuREZ$C6uufWweE/SlvDK18.8Gz9WoMZ5u72Wljy/gZFOYNDxONQzGJyq5NDQbPEfBtPXDQ8cSOCvczyfvAlvBTatdY.
True
加密后的密文确认完全等于 原始加密密文。
因此,我们的计算方式完全可行。
2.3 加密密文破解
# coding=utf-8
import crypt
shadow_file = "/etc/shadow" # 获取系统密码路径
password_file = "/sandstar_aosp/projects/wordlist.txt" # 自己的密码文件,里面放的是明文密码
def get_pass(shadow_file):used = {} # key是用户,value是对应的密文f = open(shadow_file, "r") # 读取系统密码文件userline = f.readlines() # 将该文件转换为列表格式f.close()for item in userline: # 遍历列表里的内容if len(item.split(":")[1]) > 3: # 以":"分割,取第二个元素的长度,也就是完整密文值的长度,如果大于3,我们认定它有密码,把它取出来used[item.split(":")[0]] = item.split(":")[1] # 我们将取出的密文给了相应的用户,这里的used[i.split(":")[0]]是字典的key,也就是系统中的用户名,后面的i.split(":")[1]是用户名后的加密密文return used
# 提取自己的密码文件中的明文密码
def look_d(password_file):f = open(password_file, 'r')mwlist = f.readlines() # 将读取的内容转换为列表f.close()for i, item in enumerate(mwlist):mwlist[i] = item.strip("\n") # 去除每一行的换行符return mwlist # 返回这个列表
# 根据密文是否相同判断出对应的用户和密码
def main(user_passfile, zidian):used = get_pass(user_passfile) # 获取用户和对用的加密密文mingwen = look_d(zidian) # 获取所有的明文密码for user in used:passwd = used[user] # 一次遍历每个用户的密文salt = "$6$" + passwd.split("$")[2] # 获取盐值for passwdmw in mingwen: # 遍历系统中的每个完整密文if passwd == crypt.crypt(passwdmw.rstrip(), salt): # 如果我们猜想的密文与系统中的密文相同,输入它的用户名和密码print("userName:%s passWord:%s" % (user, passwdmw.rstrip()))
if __name__ == "__main__":main(shadow_file, password_file)
wordlist.txt中存储猜测的密码。
111111
123456
test
如果破解成功的话,能够得到test的密码是test
root@ubuntu:/sandstar_aosp/projects# python sha_manual_decrypt.py
userName:test passWord:test
root@ubuntu:/sandstar_aosp/projects#
程序执行以后,我们得到了对应的密码破解账号:test的密码是test,破解成功。
参考博文:
linux下SHA-512加密及暴力破解-蒲公英云 (dandelioncloud.cn)
三、内置用户和密码
通过上面的内容,我们知道了用户信息的存储,密码的存储。根据原理,我们是否可以通过修改存储内容,内置添加用户和密码,而不需要通过执行useradd+passwd添加用户呢?
增加一个内置用户:cook(4100) cook(4100) 用户密码:123456
3.1 内置增加一个用户
修改/etc/passwd,末尾添加cook用户信息。
cook:用户名
UID:4100
组ID:4100
家目录:/home/cook
解释程序:/bin/sh
cook:x:4100:4100::/home/cook:/bin/sh
添加以后,我们查看cook账户信息:
root@ubuntu:/etc# id cook
uid=4100(cook) gid=4100 groups=4100
root@ubuntu:/etc# id test
uid=4000(test) gid=4000(test) groups=4000(test)
存在问题:
我们看到组ID已经存在,但是组名称不存在?
怎么内置组cook?参考【1.2.4 组信息保存】
3.2 内置组信息
需要内置组 cook 组ID:4100
修改组文件/etc/group,添加组cook
cook:x:4100:
组 cook的组ID4100
添加完成,我们再查询cook用户和组信息
root@ubuntu:/etc# id cook
uid=4100(cook) gid=4100(cook) groups=4100(cook)
root@ubuntu:/etc#
cook的组为cook, 组ID为4100,达到预期,完美。
3.3 内置用户密码
修改/etc/shadow,需要添加cook的密码。
设置cook密码为:123456,随机数87, 盐值:$6$87/3iIoSW7IUA,加密密文:
$6$87/3iIoSW7IUA$u6M/4PgLWF9QhZdz9Su.zIGvB9SJc.ZpKDTiWENRyvnsW2MdgF6ho.YEVSZO.oAnSdcktzA1p3ZluMoMx7ZaS/
将用户密码信息添加到/etc/shadow结尾。
cook:$6$87/3iIoSW7IUA$u6M/4PgLWF9QhZdz9Su.zIGvB9SJc.ZpKDTiWENRyvnsW2MdgF6ho.YEVSZO.oAnSdcktzA1p3ZluMoMx7ZaS/:19584:0:99999:7:::
- 用户名:cook
- 加密密码:$6$87/3iIoSW7IUA$u6M/4PgLWF9QhZdz9Su.zIGvB9SJc.ZpKDTiWENRyvnsW2MdgF6ho.YEVSZO.oAnSdcktzA1p3ZluMoMx7ZaS/
- 上次密码更改日期:
19688
- 密码更改最小天数:
0
- 密码更改最大天数:
99999
- 密码警告天数:
7
- 密码不活动天数:(为空)
- 帐户过期日期:(为空)
- 保留字段:(为空)
cook用户的密码添加成功。
root@ubuntu:/sandstar_aosp/projects# su cook
$
root用户切换cook成功。
3.4 验证内置用户登录
采用cook用户账号登录。
用户登录成功。
$ whoami
cook
$
cook密码内置成功,完美。
四、安卓账户体系
在Android开源项目(AOSP)中,默认情况下,root用户是没有密码的。在标准的Android系统中,出于安全考虑,普通应用无法获取root权限,而且大多数设备的生产商也会锁定bootloader,防止用户刷入自定义的、具有root访问权限的系统。
4.1 确认AOSP账户密码情况
当前ROM下的账户密码情况:
存在分组文件/etc/group, /etc/passwd,但是内容为空。
不存在密码存储文件 /etc/shadow
lahaina:/etc # cat /etc/group
lahaina:/etc # cat /etc/passwd
user版本没有vi命令,且adb环境下不允许修改文件内容。
lahaina:/etc # echo 'root:x:0:' > /etc/group
根据【三、内置用户和密码】,我们需要实现
- 添加root分组到 /etc/group
- 添加root用户到 /etc/passwd
- 创建密码保存文件/etc/shadow,并且 添加用户密码到 /etc/shadow
这几个步骤就是内置root密码需要实现的步骤。
我们查看root账户的信息
1|lahaina:/etc # id root
uid=0(root) gid=0(root) groups=0(root) context=u:r:su:s0
我们看到root账户已经创建,所属分组root,分组id(0), 关联组root,上下文:SELinux:u:r:su:s0
与我们看到的Linux账号密码管理有些区别?这是什么原因呢?
内容信息没有保存,却能够查看已经内置了账户信息
同理我们查看system用户:
lahaina:/etc # id system
uid=1000(system) gid=1000(system) groups=1000(system) context=u:r:su:s0
4.2 Linux和Android用户账号信息区别
在Android Open Source Project (AOSP) 或任何基于Linux的Android系统中,root账户和分组信息与传统的Linux系统有些不同,因为Android对Linux内核进行了定制,以及对用户和权限模型进行了调整以增强移动设备的安全性。
在传统的Linux系统中,如前所述,root账户和分组信息存储在 /etc/passwd
和 /etc/group
文件中。在Android系统中,这些信息仍然存在,但通常不直接用于访问控制。Android使用一种不同的权限模型,每个应用都运行在其自己的用户ID下,这些ID在安装应用时自动分配。
对于root用户(即超级用户或管理员):
- UID: 在Android中,root用户的UID是0,这与传统的Linux系统一致。
- GID: root用户所属的主要组也通常是0,表示超级用户组。
在标准的Android系统中,这些信息并不存储在文件系统中的某个文件里,而是在系统构建过程中硬编码到系统中。例如,root用户的权限是由系统在启动时设置的,而不是由存储在文件中的账户信息确定的。
对于分组信息,Android定义了一系列的特殊组,这些组用于控制对系统资源的访问。这些组的定义通常在系统的编译时确定,并且与文件系统中的权限位和SELinux策略一起工作,以实现安全模型。
在Android系统中,如果你想查看用户和组的相关信息,你可以通过访问系统的/data/system/packages.list
和 /data/system/packages.xml
文件来获取已安装应用的UID和GID信息。这些文件包含了应用的包名和分配给它们的UID。
对于开发者和那些有root权限的用户来说,可以通过ADB shell或者终端模拟器应用来访问Android设备的shell,并使用像id
、ls -l
这样的命令来查看文件的所有者和组信息。但是需要注意的是,大多数商业Android设备默认情况下不允许用户访问root账户。
如果是这样,要内置账户密码又该如何应对呢?