Linux 无法本地登录解决方法 报错/lib/security/pam_limits.so

前一段时间,因工作需要在物理机上装了一个Centos6.5,但是,用了一段时间,发现再登录时,无论如何也登不进去了,并且也不提示用户名或者密码错误。我一度以为是在profile以及.bashrc或者.bash_profile里设置了logout命令,于是乎进入单用户模式,各种查看,也没有发现logout的命令。于是,盯着屏幕瞅了一会儿,发现输入正确的用户名和密码以后,会闪一下,但是,特别快,不多瞅几次,无法识别。经过一番细瞅,发现是:Module is unkown,太好了,找解决问题的方法,有提示信息就解决了一半了。

于是,找度娘:

热心网友提供的解决问题的方法是这样的:

1、进入单用户模式

2、查看/var/log/secure文件,日志如下:

Mar 14 11:05:06 testOpenfire login: PAM unable to dlopen(/lib/security/pam_limits.so): /lib/security/pam_limits.so: cannot open shared object file: No such file or directory
Mar 14 11:05:06 testOpenfire login: PAM adding faulty module: /lib/security/pam_limits.so
Mar 14 11:05:10 testOpenfire login: pam_limits(login:session): unknown limit type ‘herd’
Mar 14 11:05:10 testOpenfire login: pam_unix(login:session): session opened for user root by LOGIN(uid=0)
Mar 14 11:05:10 testOpenfire login: Module is unknown
Mar 14 11:05:21 testOpenfire login: PAM unable to dlopen(/lib/security/pam_limits.so): /lib/security/pam_limits.so: cannot open shared object file: No such file or directory

意思是PAM unable to dlopen /lib/security/pam_limits.so这个文件,于是乎去/lib/security/下查看下有没有pam_limits.so这个文件,果然没有。

3、在/etc/pam.d/login里,里面的配置信息如下:

auth [user_unknown=ignore success=ok ignore=ignore default=bad] pam_securetty.so
auth       include      system-auth
account    required     pam_nologin.so
account    include      system-auth
password   include      system-auth
# pam_selinux.so close should be the first session rule
session    required     pam_selinux.so close
session    required     pam_loginuid.so
session    optional     pam_console.so
# pam_selinux.so open should only be followed by sessions to be executed in the user context
session    required     pam_selinux.so open
session    required     pam_namespace.so
session    optional     pam_keyinit.so force revoke
session    include      system-auth
-session   optional     pam_ck_connector.so
session required /lib/security/pam_limits.so
~
~

经网友指点,将*后一行注释掉或者是改为(搜了下,64位系统在lib64目录下):/lib64/security/pam_limits.so,保存后,重启系统。

4、用原来的用户名和密码登录,完美登录!!

据说,用SSH登录是没有问题的,但是,我的机器IP已经变了,只能登录本机,所以,必须要解决这个问题。但是,我之前用的时候,感觉没有动过这块儿,不知道为啥突然就不能用了。好在问题解决了。真是完美!!

ftp上传错误,提示:打开FTP服务器上的文件夹时发生错误,请检查是否有权限访问该文件夹。

使用FTP上传数据的时候,经常会遇到“打开FTP”无权限的提示,这是由于浏览器设置了防火墙的缘故,下面是正确的设置流程:
1. 首先打开一个IE浏览器(如果打开了多个浏览器,请关闭)。
2.点击打开“工具”—“internet选项”—“高级”
3.找到使用被动FTP(为防火墙和DSL调制解调器兼容性),并把前面的勾去掉。
4. 然后点击确定并且关闭IE浏览器。
5. 打开“我的电脑”,在地址栏里输入ip 回车,会弹出对话框,要求输入用户名和密码,输入用户名和密码后,就可以把您的压缩文件复制到ftp里了。下面是使用ftp软件flashFxp来上传得使用方法。
1. 首先打开软件 打开“选项”—“参数设置”—“代理”,把“使用被动模式”的勾去掉,确定。
2.点击右侧闪电图标,出现 在服务器栏输入ip 然后输入用户名和密码,然后点击连接就可以了。软件左侧为您的本机,右侧为服务器,把您要上传得数据帐套拖动到右侧就可以了

linux 系统时间隔一段时间,总会被还原问题

*近,在Linux使用过程中,系统时间与实际时间间隔8小时,并且修改过后隔一段时间就会被还原,且时间间隔为1分钟左右。为解决该问题尝试过多种修改时间的方法,包括设置系统时间和硬件时间,*后发现utc时间不正确,和实际时间相同(本应要提早8小时),于是采用本地时间更新成 UTC 时间解决了该问题(没有找到原因,只解决了问题)。

Linux服务器执行时发现系统时间不对,所以查找资料,首先用到了 date 来修改系统日期

1,使用 tzselect 来设置时区  选了 Asia/China/Beijing,无效;

2,修改Linux时间:date -s 时间

这种方式只是临时修改系统时间,当系统重新启动的时候就会还原。

3,而后使用 timedatectl 指令来修改时间

timedatectl set-time  ‘2019-03-16 10:10:00’
4,此时发现时间仍旧会被还原,而且是过一分钟左右,系统时间会自动更新,相隔8小时,

猜测系统时间读取的是硬件时间,于是使用 hwclock 设置硬件时间

hwclock –set –date ‘2019-03-16 10:10:00’
这是修改硬件的时间 也就是永久性修改Linux的时间

hwclock –show 查看硬件的时间
hwclock –set –date ‘2019-03-16 10:10:00’ 设置硬件时间为19年3月16日10点10分00秒
hwclock –hctosys 设置系统时间和硬件时间同步
clock -w 保存时钟
5,经过以上操作,发现LINUX系统时间仍然会定时更新,

猜测:觉得是有地方设置了定时同步,只是同步时间源不对。

尝试方法:根据网上资料,尝试网络时间同步的方式,使用 timedatectl 开启 ntp 同步,timedatectl set-ntp 1

#timedatectl
……
NTP enabled: yes
NTP synchronized: no
RTC in local TZ: no
DST active: n/a
6,此处与网友贴出的信息有所不一致, ntp enabled 虽然开启,,但是 synchronized 仍然关闭(使用 ntp update [serverip]仍无效),就算设置了 RTC in local TZ 开启也没有效果,没有找到出现此问题的原因所在

Warning: Ignoring the TZ variable. Reading the system’s time zone setting only.
Local time: 五 2019-03-29 09:05:38 UTC
Universal time: 五 2019-03-29 09:05:38 UTC
RTC time: 五 2019-03-29 00:57:06
Time zone: Universal (UTC, +0000)
NTP enabled: yes
NTP synchronized: no
RTC in local TZ: no
DST active: n/a
猜测:看到UTC的时间一直不正确,猜想是由于UTC时间导致的

解决方法:将 localtime时间重置,并将utc时间设置为localtime时间

rm /etc/localtime
#Step 4:从/usr/share/zoneinfo/中创建软连接以替换当前的时区信息,直接选择Universal:

ln -s /usr/share/zoneinfo/Universal /etc/localtime

Linux_终端直接执行py文件,不需要python命令

先将终端所在路径切换到python脚本文件的目录下
然后给脚本文件运行权限,一般755就OK,如果完全是自己的私人电脑,也不做服务器什么的,给777的权限问题也不大(具体权限含义参考chmod指令的介绍,就不赘述了):
chmod 755 ./*.py
然后执行。
如果在脚本内容的开头已经给出了类似于如下的注释:
#!/usr/bin/env python
那就可以直接在终端里运行:
./*.py
如果没有这个注释
就在终端中执行:
python ./*.py
如果是有图形界面的脚本
在前面的chmod之后,直接双击(KDE桌面是单击)文件来执行即可

Android的安全机制

Android是一个基于Linux内核的移动操作系统。Linux是一个支持多用户的系统,系统中的文件的访问权限是通过用户ID(UID)和用户组ID(GID)来控制的。换句话说,就是Linux的安全机制是基于UID和GID来实现的。Android在Linux内核提供的基于UID和GID的安全机制的基础上,又实现了一套称为Permission的安全机制,如图1所示:

 

 

%title插图%num

图1 Linux的UID/GID安全机制与Android的Permission安全机制

那么,这两个安全机制是如何对应起来的呢?

我们首先看一下Linux基于UID和GID的安全机制,它包含三个基本角色:用户、进程和文件,如图2所示:

%title插图%num

图2 Linux基于UID/GID的安全机制的三个角色

Linux中的每一个用户都分配有一个UID,然后所有的用户又按组来进划分,每一个用户组都分配有一个GID。注意,一个用户可以属于多个用户组,也就是说,一个UID可以对应多个GID。在一个用户所对应的用户组中,其中有一个称为主用户组,其它的称为补充用户组。

Linux中的每一个文件都具有三种权限:Read、Write和Execute。这三种权限又按照用户属性划分为三组:Owner、Group和Other。如图3所示:

%title插图%num

图3 Linux的文件权限划分

从图3就可以看出文件acct:1. 所有者为root,可读可写可执行;2. 所有者所属的主用户组为root,在这个组中的其它用户可读可执行;3. 其余的用户可读可执行。

Linux中的每一个进程都关联有一个用户,也就是对应有一个UID,如图4所示:

%title插图%num

图4 Linux的进程

由于每一个用户都对应有一个主用户组,以及若干个补充用户组,因此,每一个进程除了有一个对应的UID之外,还对应有一个主GID,以及若干个Supplementary GIDs。这些UID和GID就决定了一个进程所能访问的文件或者所能调用的系统API。例如,在图4中,PID为340的进程一般来说,就只能访问所有者为u0_a19的文件。

一个进程的UID是怎么来的呢?在默认情况下,就等于创建它的进程的UID,也就是它的父进程的UID。Linux的*个进程是init进程,它是由内核在启动完成后创建的,它的UID是root。然后系统中的所有其它进程都是直接由init进程或者间接由init进程的子进程来创建。所以默认情况下,系统的所有进程的UID都应该是root。但是实际情况并非如此,因为父进程在创建子进程之后,也就是在fork之后,可以调用setuid来改变它的UID。例如,在PC中,init进程启动之后,会先让用户登录。用户登录成功后,就对应有一个shell进程。该shell进程的UID就会被setuid修改为所登录的用户。之后系统中创建的其余进程的UID为所登录的用户。

进程的UID除了来自于父进程之外,还有另外一种途径。上面我们说到,Linux的文件有三种权限,分别是Read、Wirte和Execute。其实还有另外一个种权限,叫做SUID。例如,我们对Android手机进行root的过程中,会在里面放置一个su文件。这个su文件就具有SUID权限,如图5所示:

%title插图%num

图5 su的SUID和SGID

一个可执行文件一旦被设置了SUID位,那么当它被一个进程通过exec加载之后,该进程的UID就会变成该可执行文件的所有者的UID。也就是说,当上述的su被执行的时候,它所运行在的进程的UID是root,于是它就具有*高级别的权限,想干什么就干什么。

与SUI类似,文件还有另外一个称为SGID的权限,不过它描述的是用户组。也就是说,一个可执行文件一旦被设置了GUID位,么当它被一个进程通过exec加载之后,该进程的主UID就会变成该可执行文件的所有者的主UID。

现在,小伙伴们应该可以理解Android手机的root原理了吧:一个普通的进程通过执行su,从而获得一个具有root权限的进程。有了这个具有root权限的进程之后,就可以想干什么就干什么了。su所做的事情其实很简单,它再fork另外一个子进程来做真正的事情,也就是我们在执行su的时候,后面所跟的那些参数。由于su所运行在的进程的UID是root,因此由它fork出来的子进程的UID也是root。于是,子进程也可以想干什么就干什么了。

不过呢,用来root手机的su还会配合另外一个称为superuser的app来使用。su在fork子进程来做真正的事情之前,会将superuser启动起来,询问用户是否允许fork一个UID是root的子进程。这样就可以对root权限进行控制,避免被恶意应用偷偷地使用。

这里是su的源代码,小伙伴们可以根据上面所讲的知识读一读:https://code.google.com/p/superuser/source/browse/trunk/su/su.c?r=2。

在传统的UNIX以及类UNIX系统中,进程的权限只划分两种:特权和非特权。UID等于0的进程就是特权进程,它们可以通过一切的权限检查。UID不等于0的进程就非特权进程,它们在访问一些敏感资源或者调用一个敏感API时,需要进行权限检查。这种纯粹通过UID来做权限检查的安全机制来粗放了。于是,Linux从2.2开始,从进程的权限进行了细分,称为Capabilities。一个进程所具有Capabilities可以通过capset和prctl等系统API来设置。也就是说,当一个进程调用一个敏感的系统API时,Linux内核除了考虑它的UID之外,还会考虑它是否具有对应的Capability。

这里就是Linux所设计的Capabilities列表,有兴趣的小伙伴可以再读一读:http://man7.org/linux/man-pages/man7/capabilities.7.html。

以上就是Linux基于UID/GID的安全机制的核心内容。接下来我们再看Android基于Permission的安全机制,它也有三个角色:apk、signature和permission,如图6所示:

%title插图%num

图6 Android的Permission安全机制

 

Android的APK经过PackageManagerService安装之后,就相当于Linux里面的User,它们都会被分配到一个UID和一个主GID,而APK所申请的Permission就相当于是Linux里面的Supplementary GID。

我们知道,Android的APK都是运行在独立的应用程序进程里面的,并且这些应用程序进程都是Zygote进程fork出来的。Zygote进程又是由init进程fork出来的,并且它被init进程fork出来后,没有被setuid降权,也就是它的uid仍然是root。按照我们前面所说的,应用程序进程被Zygote进程fork出来的时候,它的UID也应当是root。但是,它们的UID会被setuid修改为所加载的APK被分配的UID。

参照Android应用程序进程启动过程的源代码分析一文的分析,ActivityManagerService在请求Zygote创建应用程序进程的时候,会将这个应用程序所加载的APK所分配得到的UID和GID(包括主GID和Supplementary GID)都收集起来,并且将它们作为参数传递给Zygote进程。Zygote进程通过执行函数来fork应用程序进程:

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片

  1. /*
  2.  * Utility routine to fork zygote and specialize the child process.
  3.  */
  4. static pid_t forkAndSpecializeCommon(const u4* args, bool isSystemServer)
  5. {
  6.     pid_t pid;
  7.     uid_t uid = (uid_t) args[0];
  8.     gid_t gid = (gid_t) args[1];
  9.     ArrayObject* gids = (ArrayObject *)args[2];
  10.     ……
  11.     pid = fork();
  12.     if (pid == 0) {
  13.         ……
  14.         err = setgroupsIntarray(gids);
  15.         ……
  16.         err = setgid(gid);
  17.         ……
  18.         err = setuid(uid);
  19.         ……
  20.     }
  21.     …..
  22.     return pid;
  23. }

参数args[0]、args[1]和args[]保存的就是APK分配到的UID、主GID和Supplementary GID,它们分别通过setuid、setgid和setgroupsIntarray设置给当前fork出来的应用程序进程,于是应用程序进程就不再具有root权限了。

那么,Signature又充当什么作用呢?两个作用:1. 控制哪些APK可以共享同一个UID;2. 控制哪些APK可以申请哪些Permission。

我们知道,如果要让两个APK共享同一个UID,那么就需要在AndroidManifest中配置android:sharedUserId属性。PackageManagerService在安装APK的时候,如果发现两个APK具有相同的android:sharedUserId属性,那么它们就会被分配到相同的UID。当然这有一个前提,就是这两个APK必须具有相同的Signature。这很重要,否则的话,如果我知道别人的APK设置了android:sharedUserId属性,那么我也在自己的APK中设置相同的android:sharedUserId属性,就可以去访问别人APK的数据了。

除了可以通过android:sharedUserId属性申请让两个APK共享同一个UID之外,我们还可以将android:sharedUserId属性的值设置为“android.uid.system”,从而让一个APK的UID设置为1000。UID是1000的用户是system,系统的关键服务都是运行在的进程的UID就是它。它的权限虽然不等同于root,不过也足够大了。我们可以通过Master Key漏洞来看一下有多大。

Master Key漏洞发布时,曾轰动了整个Android界,它的具体情况老罗就不分析了,网上很多,这里是一篇官方的文章:http://bluebox.com/corporate-blog/bluebox-uncovers-android-master-key/。现在就简单说说它是怎么利用的:

1. 找到一个具有系统签名的APP,并且这个APP通过android:sharedUserId属性申请了android.uid.system这个UID。

2. 通过Master Key向这个APP注入恶意代码。

3. 注入到这个APP的恶意代码在运行时就获得了system用户身份。

4. 修改/data/local.prop文件,将属性ro.kernel.qemu的值设置为1。

5. 重启手机,由于ro.kernel.qemu的值等于1,这时候手机里面的adb进程不会被setuid剥夺掉root权限。

6. 通过具有root权限的adb进程就可以向系统注入我们熟悉的su和superuser.apk,于是整个root过程完成。

注意,第1步之所以要找一个具有系统签名的APP,是因为通过android:sharedUserId属性申请android.uid.system这个UID需要有系统签名,也就是说不是谁可以申请system这个UID的。另外,/data/local.prop文件的Owner是system,因此,只有获得了system这个UID的进程,才可以对它进行修改。

再说说Signature与Permission的关系。有些Permission,例如INSTALL_PACKAGE,不是谁都可以申请的,必须要具有系统签名才可以,这样就可以控制Suppementary GID的分配,从而控制应用程序进程的权限。具有哪些Permission是具有系统签名才可以申请的,可以参考官方文档:http://developer.android.com/reference/android/Manifest.html,就是哪些标记为“Not for use by third-party applications”的Permission。

了解了Android的Permission机制之后,我们就可以知道:

1. Android的APK就相当于是Linux的UID。

2. Android的Permission就相当于是Linux的GID。

3. Android的Signature就是用来控制APK的UID和GID分配的。

这就是Android基于Permission的安全机制与Linux基于UID/GID的安全机制的关系,概括来说,我们常说的应用程序沙箱就是这样的:

%title插图%num

图7 Android的Application Sandbox

Android是一个基于Linux内核的移动操作系统。Linux是一个支持多用户的系统,系统中的文件的访问权限是通过用户ID(UID)和用户组ID(GID)来控制的。换句话说,就是Linux的安全机制是基于UID和GID来实现的。Android在Linux内核提供的基于UID和GID的安全机制的基础上,又实现了一套称为Permission的安全机制,如图1所示:

%title插图%num

图1 Linux的UID/GID安全机制与Android的Permission安全机制

那么,这两个安全机制是如何对应起来的呢?

我们首先看一下Linux基于UID和GID的安全机制,它包含三个基本角色:用户、进程和文件,如图2所示:

%title插图%num

图2 Linux基于UID/GID的安全机制的三个角色

Linux中的每一个用户都分配有一个UID,然后所有的用户又按组来进划分,每一个用户组都分配有一个GID。注意,一个用户可以属于多个用户组,也就是说,一个UID可以对应多个GID。在一个用户所对应的用户组中,其中有一个称为主用户组,其它的称为补充用户组。

Linux中的每一个文件都具有三种权限:Read、Write和Execute。这三种权限又按照用户属性划分为三组:Owner、Group和Other。如图3所示:

%title插图%num

图3 Linux的文件权限划分

从图3就可以看出文件acct:1. 所有者为root,可读可写可执行;2. 所有者所属的主用户组为root,在这个组中的其它用户可读可执行;3. 其余的用户可读可执行。

Linux中的每一个进程都关联有一个用户,也就是对应有一个UID,如图4所示:

%title插图%num

图4 Linux的进程

由于每一个用户都对应有一个主用户组,以及若干个补充用户组,因此,每一个进程除了有一个对应的UID之外,还对应有一个主GID,以及若干个Supplementary GIDs。这些UID和GID就决定了一个进程所能访问的文件或者所能调用的系统API。例如,在图4中,PID为340的进程一般来说,就只能访问所有者为u0_a19的文件。

一个进程的UID是怎么来的呢?在默认情况下,就等于创建它的进程的UID,也就是它的父进程的UID。Linux的*个进程是init进程,它是由内核在启动完成后创建的,它的UID是root。然后系统中的所有其它进程都是直接由init进程或者间接由init进程的子进程来创建。所以默认情况下,系统的所有进程的UID都应该是root。但是实际情况并非如此,因为父进程在创建子进程之后,也就是在fork之后,可以调用setuid来改变它的UID。例如,在PC中,init进程启动之后,会先让用户登录。用户登录成功后,就对应有一个shell进程。该shell进程的UID就会被setuid修改为所登录的用户。之后系统中创建的其余进程的UID为所登录的用户。

进程的UID除了来自于父进程之外,还有另外一种途径。上面我们说到,Linux的文件有三种权限,分别是Read、Wirte和Execute。其实还有另外一个种权限,叫做SUID。例如,我们对Android手机进行root的过程中,会在里面放置一个su文件。这个su文件就具有SUID权限,如图5所示:

%title插图%num

图5 su的SUID和SGID

一个可执行文件一旦被设置了SUID位,那么当它被一个进程通过exec加载之后,该进程的UID就会变成该可执行文件的所有者的UID。也就是说,当上述的su被执行的时候,它所运行在的进程的UID是root,于是它就具有*高级别的权限,想干什么就干什么。

与SUI类似,文件还有另外一个称为SGID的权限,不过它描述的是用户组。也就是说,一个可执行文件一旦被设置了GUID位,么当它被一个进程通过exec加载之后,该进程的主UID就会变成该可执行文件的所有者的主UID。

现在,小伙伴们应该可以理解Android手机的root原理了吧:一个普通的进程通过执行su,从而获得一个具有root权限的进程。有了这个具有root权限的进程之后,就可以想干什么就干什么了。su所做的事情其实很简单,它再fork另外一个子进程来做真正的事情,也就是我们在执行su的时候,后面所跟的那些参数。由于su所运行在的进程的UID是root,因此由它fork出来的子进程的UID也是root。于是,子进程也可以想干什么就干什么了。

不过呢,用来root手机的su还会配合另外一个称为superuser的app来使用。su在fork子进程来做真正的事情之前,会将superuser启动起来,询问用户是否允许fork一个UID是root的子进程。这样就可以对root权限进行控制,避免被恶意应用偷偷地使用。

这里是su的源代码,小伙伴们可以根据上面所讲的知识读一读:https://code.google.com/p/superuser/source/browse/trunk/su/su.c?r=2。

在传统的UNIX以及类UNIX系统中,进程的权限只划分两种:特权和非特权。UID等于0的进程就是特权进程,它们可以通过一切的权限检查。UID不等于0的进程就非特权进程,它们在访问一些敏感资源或者调用一个敏感API时,需要进行权限检查。这种纯粹通过UID来做权限检查的安全机制来粗放了。于是,Linux从2.2开始,从进程的权限进行了细分,称为Capabilities。一个进程所具有Capabilities可以通过capset和prctl等系统API来设置。也就是说,当一个进程调用一个敏感的系统API时,Linux内核除了考虑它的UID之外,还会考虑它是否具有对应的Capability。

这里就是Linux所设计的Capabilities列表,有兴趣的小伙伴可以再读一读:http://man7.org/linux/man-pages/man7/capabilities.7.html。

以上就是Linux基于UID/GID的安全机制的核心内容。接下来我们再看Android基于Permission的安全机制,它也有三个角色:apk、signature和permission,如图6所示:

%title插图%num

图6 Android的Permission安全机制

 

Android的APK经过PackageManagerService安装之后,就相当于Linux里面的User,它们都会被分配到一个UID和一个主GID,而APK所申请的Permission就相当于是Linux里面的Supplementary GID。

我们知道,Android的APK都是运行在独立的应用程序进程里面的,并且这些应用程序进程都是Zygote进程fork出来的。Zygote进程又是由init进程fork出来的,并且它被init进程fork出来后,没有被setuid降权,也就是它的uid仍然是root。按照我们前面所说的,应用程序进程被Zygote进程fork出来的时候,它的UID也应当是root。但是,它们的UID会被setuid修改为所加载的APK被分配的UID。

参照Android应用程序进程启动过程的源代码分析一文的分析,ActivityManagerService在请求Zygote创建应用程序进程的时候,会将这个应用程序所加载的APK所分配得到的UID和GID(包括主GID和Supplementary GID)都收集起来,并且将它们作为参数传递给Zygote进程。Zygote进程通过执行函数来fork应用程序进程:

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片

  1. /*
  2.  * Utility routine to fork zygote and specialize the child process.
  3.  */
  4. static pid_t forkAndSpecializeCommon(const u4* args, bool isSystemServer)
  5. {
  6.     pid_t pid;
  7.     uid_t uid = (uid_t) args[0];
  8.     gid_t gid = (gid_t) args[1];
  9.     ArrayObject* gids = (ArrayObject *)args[2];
  10.     ……
  11.     pid = fork();
  12.     if (pid == 0) {
  13.         ……
  14.         err = setgroupsIntarray(gids);
  15.         ……
  16.         err = setgid(gid);
  17.         ……
  18.         err = setuid(uid);
  19.         ……
  20.     }
  21.     …..
  22.     return pid;
  23. }

参数args[0]、args[1]和args[]保存的就是APK分配到的UID、主GID和Supplementary GID,它们分别通过setuid、setgid和setgroupsIntarray设置给当前fork出来的应用程序进程,于是应用程序进程就不再具有root权限了。

那么,Signature又充当什么作用呢?两个作用:1. 控制哪些APK可以共享同一个UID;2. 控制哪些APK可以申请哪些Permission。

我们知道,如果要让两个APK共享同一个UID,那么就需要在AndroidManifest中配置android:sharedUserId属性。PackageManagerService在安装APK的时候,如果发现两个APK具有相同的android:sharedUserId属性,那么它们就会被分配到相同的UID。当然这有一个前提,就是这两个APK必须具有相同的Signature。这很重要,否则的话,如果我知道别人的APK设置了android:sharedUserId属性,那么我也在自己的APK中设置相同的android:sharedUserId属性,就可以去访问别人APK的数据了。

除了可以通过android:sharedUserId属性申请让两个APK共享同一个UID之外,我们还可以将android:sharedUserId属性的值设置为“android.uid.system”,从而让一个APK的UID设置为1000。UID是1000的用户是system,系统的关键服务都是运行在的进程的UID就是它。它的权限虽然不等同于root,不过也足够大了。我们可以通过Master Key漏洞来看一下有多大。

Master Key漏洞发布时,曾轰动了整个Android界,它的具体情况老罗就不分析了,网上很多,这里是一篇官方的文章:http://bluebox.com/corporate-blog/bluebox-uncovers-android-master-key/。现在就简单说说它是怎么利用的:

1. 找到一个具有系统签名的APP,并且这个APP通过android:sharedUserId属性申请了android.uid.system这个UID。

2. 通过Master Key向这个APP注入恶意代码。

3. 注入到这个APP的恶意代码在运行时就获得了system用户身份。

4. 修改/data/local.prop文件,将属性ro.kernel.qemu的值设置为1。

5. 重启手机,由于ro.kernel.qemu的值等于1,这时候手机里面的adb进程不会被setuid剥夺掉root权限。

6. 通过具有root权限的adb进程就可以向系统注入我们熟悉的su和superuser.apk,于是整个root过程完成。

注意,第1步之所以要找一个具有系统签名的APP,是因为通过android:sharedUserId属性申请android.uid.system这个UID需要有系统签名,也就是说不是谁可以申请system这个UID的。另外,/data/local.prop文件的Owner是system,因此,只有获得了system这个UID的进程,才可以对它进行修改。

再说说Signature与Permission的关系。有些Permission,例如INSTALL_PACKAGE,不是谁都可以申请的,必须要具有系统签名才可以,这样就可以控制Suppementary GID的分配,从而控制应用程序进程的权限。具有哪些Permission是具有系统签名才可以申请的,可以参考官方文档:http://developer.android.com/reference/android/Manifest.html,就是哪些标记为“Not for use by third-party applications”的Permission。

了解了Android的Permission机制之后,我们就可以知道:

1. Android的APK就相当于是Linux的UID。

2. Android的Permission就相当于是Linux的GID。

3. Android的Signature就是用来控制APK的UID和GID分配的。

这就是Android基于Permission的安全机制与Linux基于UID/GID的安全机制的关系,概括来说,我们常说的应用程序沙箱就是这样的:

%title插图%num

图7 Android的Application Sandbox

linux 下查看机器配置命令

cat /proc/ cpuinfo

或者vim /proc/ cpuinfo

查看系统信息

cat /proc/ cpuinfo – CPU (i.e. vendor, Mhz, flags like mmx)

cat /proc/interrupts – 中断

cat /proc/ioports – 设备IO端口

cat /proc/meminfo – 内存信息(i.e. mem used, free, swap size)

cat /proc/partitions – 所有设备的所有分区

cat /proc/pci – PCI设备的信息

cat /proc/swaps – 所有Swap分区的信息

cat /proc/version – Linux的版本号 相当于 uname -r

uname -a – 看系统内核等信息

查看linux系统版本方法:

cat /etc/redhat-release

cat /etc/issue

cat /proc/version

查看磁盘空间大小:

df -m

cat /etc/issue 查看操作系统版本

cat /etc/inittab 查看启动项

cat /proc/cpuinfo 查看cpu信息

uname -a 系统版本

df -h 查硬盘

cat /etc/passwd 查看所有用户的列表

cat /etc/group 查看用户组

du -sh 查看当前文件夹大小

这里linux下使用dmidecode查看硬件信息

dmidecode is a tool for dumping a computer””s DMI (some say SMBIOS) table contents in a human-readable format. This table contains a description of the system””s hardware components, as well as other useful pieces of information such as serial numbers and BIOS revision. Thanks to this table, you can retrieve this information without having to probe for the actual hardware. While this is a good point in terms of report speed and safeness, this also makes the presented information possibly unreliable.

dmidecode可以全面的显示bios、cpu、内存等硬件信息。

查看主板的序列号

dmidecode | grep “Serial Number”

显示物理内存块数

dmidecode |grep -A16 “Memory Device$”

显示CPU信息

dmidecode |grep -A42 “Processor”|more

另外:

grep -An (A和n之间也可以有空格) 输出包含指定字符串的行及该行后续的n行

/usr/sbin/dmidecode | grep “Serial Number”可以读出计算机的标示号,当然这只对正规品牌的机器有效,如DELL、HP之类,取出的值和机器上贴的值是对应的,而类似清华同方之流的兼容机,基本上读不出任何有意义的数据。

Linux如何查看机器的硬件配置信息

主要是看两个文件: /proc/meminfo   和 /proc/cpuinfo

cpu主要关注如下字段:%title插图%num

1. cpu核心数计算:

# 总核数 = 物理CPU个数 X 每颗物理CPU的核数
# 总逻辑CPU数 = 物理CPU个数 X 每颗物理CPU的核数 X 超线程数

# 查看物理CPU个数
cat /proc/cpuinfo| grep “physical id”| sort| uniq| wc -l
[root@web ~]# cat /proc/cpuinfo| grep “physical id”| sort| uniq| wc -l
2

# 查看每个物理CPU中core的个数(即核数)
cat /proc/cpuinfo| grep “cpu cores”| uniq
[root@web ~]# cat /proc/cpuinfo| grep “cpu cores”| uniq #uniq:去除重复行

cpu cores : 8
[root@web ~]#

# 查看逻辑CPU的个数
cat /proc/cpuinfo| grep “processor”| wc -l
[root@web ~]# cat /proc/cpuinfo| grep “processor”| wc -l
32
[root@web ~]#

2. cpu型号查看:model name

# 查看CPU信息(型号)
cat /proc/cpuinfo | grep “name” | cut -f2 -d: | uniq -c
[root@web ~]# cat /proc/cpuinfo | grep name | cut -f2 -d: | uniq -c #uniq:去除重复行 -c参数:在输出行前面加上每行在输入文件中出现的次数
32 Intel(R) Xeon(R) CPU E5-2680 0 @ 2.70GHz
3、查看硬盘型号
# more /proc/scsi/scsi |grep -i model
# cat /proc/scsi/scsi |grep -i model
4. 显示有几块物理网卡

# lspci | grep Eth | wc -l
5、显示主板序列号
# dmidecode | grep ‘Serial Number’

判断linux是ubuntu还是centos

方式一:
radhat或centos存在: /etc/redhat-release 这个文件【 命令 cat /etc/redhat-release 】
ubuntu存在 : /etc/lsb-release 这个文件 【命令 cat etc/lsb-release 】
方式二:
看看安装指令,
有yum的就是Centos【yum -help】,
有apt-get的就是Ubuntu 【apt-get -help】。

linux适合做服务器,不适合做桌面

桌面的要求是,能够不停地安装各种奇怪的软件,然后再不停地卸载,不停地更新,然后几年不用重装系统!
而服务器的要求是稳定的运行,一台服务器只要安装少许几个软件,10年不需要安装新的软件,*多就是升升级而已!
所以linux复杂的库依赖问题不会对服务器造成影响,但是作为桌面,则会引起很大的问题。
linux如果能够像windows那样,库依赖问题能够很好的解决,则linux作为桌面则大有希望了,当然APT/YUM已经很好的解决这些问题了,但是还是有问题,稳定性还是不如windows.
APT/YUM做的烂(有些包依赖有错误),而且并不是所有软件都在apt/yum服务器上,有时候需要自己安装软件,这样就造成了系统的混乱!
但是为了使用*新的软件,有时候必须自己安装,这样真是无解呀!除非所有的软件发起者都主动向APT/YUM提交代码,但是可能吗?
Windows的世界可以做到每一个新硬件,都需要windows来认证一番,但是linux的世界没有一个发行版有这么大的权威性!

参考:
1. pkg-config
2. rpm/deb(dpkg):就好比exe
3. apt/yum:用来管理所有的deb/rpm