郑重声明:文中所涉及的技术、思路和工具仅供以安全为目的的学习交流使用,如果您不同意请关闭该页面!任何人不得将其用于非法用途以及盈利等目的,否则后果自行承担!

于2020/3/18日重新排版修改

根目录解析

  • / - 根目录

    每一个文件和目录都从这里开始。

    只有root用户具有该目录下的写权限。此目录和/root目录不同,/root目录是root用户的主目录。

  • /bin - 用户二进制文件

    包含二进制可执行文件。

    系统的所有用户使用的命令都设在这里,例如:ps,ls,ping,grep,cp等。

  • /sbin - 系统二进制文件

    就像/bin,/sbin同样也包含二进制可执行文件。

    但是,在这个目录下的linux命令通常由系统管理员使用,对系统进行维护。例如:iptables、reboot、fdisk、ifconfig、swapon命令。

  • /etc - 配置文件

    包含所有程序所需的配置文件。

    也包含了用于启动/停止单个程序的启动和关闭shell脚本。例如:/etc/resolv.conf、/etc/logrotate.conf

  • /dev - 设备文件

    这些包括终端设备、USB或连接到系统的任何设备。例如:/dev/tty1、/dev/usbmon0

  • /proc - 进程信息

    这是一个虚拟的文件系统,包含有关正在运行的进程的信息。例如:/proc/{pid}目录中包含的与特定pid相关的信息。

  • /var - 变量文件

    这个目录下可以找到内容可能增长的文件。比如:系统日志文件(/var/log)包和数据库文件(/var/lib)电子邮件(/var/mail)打印队列(/var/spool)锁文件(/var/lock)多次重新启动需要的临时文件(/var/tmp)

  • /tmp - 临时文件

    包含系统和用户创建的临时文件,当系统重新启动时,这个目录下的文件都将被删除。

  • /usr - 用户程序

    包含二进制文件、库文件、文档和二级程序的源代码。

    /usr/bin中包含用户程序的二进制文件。如果你在/bin中找不到用户二进制文件,到/usr/bin目录看看。例如:at、awk、cc、less、scp。

    /usr/sbin中包含系统管理员的二进制文件。如果你在/sbin中找不到系统二进制文件,到/usr/sbin目录看看。例如:atd、cron、sshd、useradd、userdel。

    /usr/lib中包含了/usr/bin和/usr/sbin用到的库。

    /usr/local中包含了从源安装的用户程序。例如,当你从源安装Apache,它会在/usr/local/apache2中。

  • /home - HOME目录

    所有用户用home目录来存储他们的个人档案。

  • /boot - 引导加载程序文件

包含引导加载程序相关的文件,内核的initrd、vmlinux、grub文件位于/boot下。

  • /lib - 系统库

    包含支持位于/bin和/sbin下的二进制文件的库文件。

  • /opt - 可选的附加应用程序

    opt代表opitional,包含从个别厂商的附加应用程序,附加应用程序应该安装在/opt/或者/opt/的子目录下。

  • /mnt - 挂载目录

    临时安装目录,系统管理员可以挂载文件系统。

  • /media - 可移动媒体设备

    用于挂载可移动设备的临时目录。举例来说,挂载CD-ROM的/media/cdrom,挂载软盘驱动器

    的/media/floppy

  • /srv - 服务数据

    包含服务器特定服务相关的数据。

日志文件

日志文件 说 明
/var/log/cron 记录与系统定时任务相关的曰志
/var/log/cups/ 记录打印信息的曰志
/var/log/dmesg 记录了系统在开机时内核自检的信总。也可以使用dmesg命令直接查看内核自检信息
/var/log/btmp 记录错误登陆的日志。这个文件是二进制文件,不能直接用Vi查看,而要使用lastb命令查看。命令如下: [root@localhost log]#lastb root tty1 Tue Jun 4 22:38 - 22:38 (00:00) #有人在6月4 日 22:38便用root用户在本地终端 1 登陆错误
/var/log/lasllog 记录系统中所有用户最后一次的登录时间的曰志。这个文件也是二进制文件.不能直接用Vi 查看。而要使用lastlog命令查看
/var/Iog/mailog 记录邮件信息的曰志
/var/log/messages 它是核心系统日志文件,其中包含了系统启动时的引导信息,以及系统运行时的其他状态消息。I/O 错误、网络错误和其他系统错误都会记录到此文件中。其他信息,比如某个人的身份切换为 root,已经用户自定义安装软件的日志,也会在这里列出。
/var/log/secure 记录验证和授权方面的倍息,只要涉及账户和密码的程序都会记录,比如系统的登录、ssh的登录、su切换用户,sudo授权,甚至添加用户和修改用户密码都会记录在这个日志文件中
/var/log/wtmp 永久记录所有用户的登陆、注销信息,同时记录系统的后动、重启、关机事件。同样,这个文件也是二进制文件.不能直接用Vi查看,而要使用last命令查看
/var/tun/ulmp 记录当前已经登录的用户的信息。这个文件会随着用户的登录和注销而不断变化,只记录当前登录用户的信息。同样,这个文件不能直接用Vi查看,而要使用w、who、users等命令查看

基础查看信息杂项

root之外,是否还有其它特权用户(uid 0)

awk -F: '$3==0{print $1}' /etc/passwd

可以远程登录的帐号信息

awk '/$1|$6/{print $1}' /etc/shadow

查看登录失败信息

grep -o "Failed password" /var/log/secure|uniq -c

输出登录爆破的第一行和最后一行,确认爆破时间范围

grep "Failed password" /var/log/secure|head -1
grep "Failed password" /var/log/secure|tail -1

查询爆破的IP有哪些

grep "Failed password for root" /var/log/auth.log | awk '{print $11}' | sort | uniq -c | sort -nr | more

爆破用户名字典都有哪些?

grep "Failed password" /var/log/secure|perl -e 'while($_=<>){ /for(.*?) from/; print "$1\n";}'|uniq -c|sort -nr

登录成功的日期、用户名、IP

grep "Accepted " /var/log/secure | awk '{print $1,$2,$3,$9,$11}' 

lastlog列出所有用户最近登录的信息

lastlog引用的是/var/log/lastlog文件中的信息,包括login-nameportlast login time

last 列出当前和曾经登入系统的用户信息

它默认读取的是/var/log/wtmp文件的信息。输出的内容包括:用户名、终端位置、登录源信息、开始时间、结束时间、持续时间。注意最后一行输出的是wtmp文件起始记录的时间。当然也可以通过last -f参数指定读取文件,可以是/var/log/btmp/var/run/utmp

语法:
last [-R] [-num] [ -n num ] [-adiowx] [ -f file ] [ -t YYYYMMDDHHMMSS ] [name...]  [tty...]

例子:
last -x :显示系统关闭、用户登录和退出的历史
last -i:显示特定ip登录的情况
last -t  20181010120101: 显示20181010120101之前的登录信息

lastb 列出失败尝试的登录信息

last命令功能完全相同,只不过它默认读取的是/var/log/btmp文件的信息。当然也可以通过last -f参数指定读取文件,可以是/var/log/btmp/var/run/utmp

统计一下登录成功的IP有哪些

grep "Accepted " /var/log/secure | awk '{print $11}' | sort | uniq -c | sort -nr | more

root帐号外,其他帐号是否存在sudo权限。如非管理需要,普通帐号应删除sudo权限

more /etc/sudoers | grep -v "^#\|^$" | grep "ALL=(ALL)"

禁用或删除多余及可疑的帐号

usermod -L user    #禁用帐号,帐号无法登录,/etc/shadow第二栏为!开头
userdel user #删除user用户
userdel -r user #将删除user用户,并且将/home目录下的user目录一并删除

增加一个用户kali日志

grep "useradd" /var/log/secure 

删除用户kali日志

grep "userdel" /var/log/secure

sudo授权执行

#查看谁有sudo授权执行权限(权限级别)
sudo -l

使用ps命令,分析进程

ps aux | grep pid (pid表示pid号)

专项使用

SSH相关操作

  • 查看当前SSH登录信息

    可以看到有哪些用户登录了,登录的时间,登录多久

    #查看当前登录用户(tty本地登陆  pts远程登录)
    root@iZbp19pfnyuhlghdkeobejZ:~# who
    root pts/0 2020-03-18 10:24 (X.X.X.X)
    root pts/1 2020-03-18 10:24 (X.X.X.X)
    #查看当前登录用户
    root@iZbp19pfnyuhlghdkeobejZ:~# last
    root pts/2 (X.X.X.X) Wed Mar 18 10:25 still logged in
    root pts/1 (X.X.X.X) Wed Mar 18 10:24 - 10:30 (00:05)
    root pts/0 (X.X.X.X) Wed Mar 18 10:24 - 10:25 (00:01)
    root pts/0 (X.X.X.X) Wed Mar 18 00:12 - 00:17 (00:04)
    reboot system boot 4.9.0-11-amd64 Wed Mar 18 08:12 still running
    #查看登陆多久、多少用户,负载
    root@iZbp19pfnyuhlghdkeobejZ:~# uptime
    23:00:23 up 22:47, 2 users, load average: 0.00, 0.01, 0.00
  • SSH隐身登录

    隐身登录系统,不会被lastwhow等指令检测到

    ssh -T root@192.168.1.1 /bin/bash -i
    ssh -o UserKnownHostsFile=/dev/null -T root@192.168.1.1 /bin/bash -if
  • SSH端口复用

    通过SSLH在同一端口上共享SSHHTTPS

    #安装SSLH
    apt install sslh
    # 配置SSLH
    # 编辑 SSLH 配置文件:
    sudo vi /etc/default/sslh
    #1、找到下列行:Run=no 将其修改为:Run=yes
    #2、修改以下行以允许 SSLH 在所有可用接口上侦听端口 443
    DAEMON_OPTS="--user sslh --listen 0.0.0.0:443 --ssh 127.0.0.1:22 --ssl 127.0.0.1:443 --pidfile /var/run/sslh/sslh.pid"
    service sslh start
  • Kali 开启SSH登录

    • 查看ssh服务状态
    /etc/init.d/ssh status

    如果显示为Active: inactive (dead)就表示没有开启

    • 修改配置文件
    vim /etc/ssh/sshd_config
    #原来文件内容
    #PermitRootLogin prohibit-password
    #PasswordAuthentication yes
    #修改后的内容
    PermitRootLogin yes
    PasswordAuthentication yes
    • 启动ssh服务
    /etc/init.d/ssh start
    • 设置为开机启动
    update-rc.d ssh enable

histroy命令

两个histroy是命令输入可以直接查看历史执行过命令,.bash_history是文件需要复制到别的文件中查看

  • 历史操作命令清除
history -c
#但此命令并不会清除保存在文件中的记录,因此需要手动删除.bash_profile文件中的记录。
  • 历史命令查看
#把文件内容发送到history.txt文件中
cat .bash_history >> history.txt
#直接查看
histroy
  • 隐藏历史操作命令

命令会临时禁用历史功能,这意味着在这命令之后你执行的所有操作都不会记录到历史中,然而这个命令之前的所有东西都会原样记录在历史列表中。

#关闭历史记录
#[space] 表示空格。并且由于空格的缘故,该命令本身也不会被记录
[space]set +o history
#开启历史记录
#执行命令之后的命令都会出现在历史中。
[Space]set -o history
netstat命令

使用netstat 网络连接命令,分析可疑端口、IPPID

netstat -antlp|more
!net
lsof -i:80 #查看指定端口
netstat -anp|grep 158.x.x.x #从连接的IP来定位PID,如果是瞬时建立的才找不到

查看下pid所对应的进程文件信息

ls -l /proc/$PID/   #可以查看详细进程信息
file /proc/$PID/exe #($PID 为对应的pid 号)
cd /proc/$PID #可以进入该进程目录
ll /proc/PID #查看程序对应的启动位置
which XXXX #查看程序在哪个文件夹 XXXX表示程序名
lsof /usr/bin/* #查看某个路径下的运行中的进程列表
pidof /usr/bin/* #查看某个路径下运行进程的 pid

查看定时任务

crontab -l #查看当前用户定时任务
cat /etc/crontab #查看定时任务的文件里面是否存在定时任务
ls -al /var/spool/cron/*
cat /var/spool/cron/* #查看文件夹里面是否有其他定时任务的文件
ls -al /etc/cron.d/*
for u in `cat /etc/passwd |cut -d ":" -f1`;do crontab -l -u $u; done #查看所有用户的定时任务
  • 删除定时任务
crontab -r #表面上删除定时任务
  • 编辑定时任务
crontab -e 
  • 定时任务解读:
#前面5个星分别代表分-时-天-月-星期 后面跟命令
* * * * * command
#(表示每15分钟运行一次)
*/15 * * * * command

查看ssh秘钥

cat .ssh/authorized_keys  #查看命令
/root/.ssh/authorized_keys #ssh秘钥文件所在路径

查看CPU运行

top

结束进程

kill PID
kill -9 PID #彻底杀死进程
kill -KILL PID #强制杀死进程

查看进程

ps -a #列出的是当前控制终端启动的进程
ps -A #系统全部启动进程
ps auxf #查看父进程关联的子进程
ps -aux #枚举进程命令行,病毒一般都携带可疑的命令行,比如带有url等奇怪的字符串时
pstree #查看进程树

开机启动的一些路径

/etc/rc.d/rc
/etc/rc
/etc/rc.local
/etc/rc.d/rc.local
/etc/rc.d/rc
/etc/rc$runlevel.d/ #该目录下都是链接的可执行文件,也可以自己添加可执行程序
/etc/ld.so.cache
/etc/ld.so.preload
/usr/local/lib/libioset.so
/etc/init.d
#另外一个添加启动项的地方在 /etc/profile里面,还有 /etc/profile.d/目录下以sh结尾的文件

封禁IP

  • 参数-I是表示Insert(添加),-D表示Delete(删除)。后面跟的是规则,INPUT表示入站,1.1.1.1表示要封停的IPDROP表示放弃连接。
iptables -I INPUT -s 1.1.1.1 -j DROP  #封禁IP进口
iptables -I OUTPUT -s 1.1.1.1/24 -j DROP #封禁IP出口
iptables -I INPUT -s 1.1.1.1/24 -j DROP #封禁IP段
iptables --list #查看规则
  • IP限制后保存信息
yum install iptables-services
chkconfig iptables on
service iptables save
cat /etc/sysconfig/iptables
service iptables start
iptables -nL

查看系统服务

  • 如果删除了计划任务,还有文件删除不了 可以查看系统服务是否存在病毒
chkconfig –list        #列出所有的系统服务
chkconfig –add httpd #增加httpd服务
chkconfig –del httpd #删除httpd服务

文件下载

  • 如果关闭了FTP,又无法使用xftp访问卡原始用scp命令下载
scp -r 目标文件路径  root@1.1.1.1:/home/

对文件进行限制

chmod 000 /usr/bin/XXXXXX  #设置一个文件权限为空(就是什么权限都没有
chattr +i /usr/bin #限制对/usr/bin路径修改
chattr -i /usr/bin #开放对/usr/bin路径修改

alias 定义或显示别名

# 显示全部已定义的别名
alias
alias -p
# 显示已定义的别名(假设当前环境存在以下别名)
alias ls
alias ls grep
# 定义或修改别名的值
alias ls='ls --color=auto'
alias ls='ls --color=never' grep='grep --color=never'

cmatrix命令

可以生成《黑客帝国》那种矩阵风格的动画效果

1575251948987

oneko 命令

输入后有一只小猫跟着你跑

查看密码

  • /etc/passwd

    #每一行都代表一个用户,每一行又通过[:]分为七个部分。
    root:x:0:0:root:/root:/bin/bash
    daemon:x:1:1:daemon:/usr/sbin:/bin/sh
    bin:x:2:2:bin:/bin:/bin/sh
    sys:x:3:3:sys:/dev:/bin/sh
    • 账号名称
    • 原先用来保存密码的,现在密码都放在/etc/shadow中,所以这里显示x
    • UID,也就是使用者ID。默认的系统管理员的UID0,我们添加用户的时候最好使用1000以上的UID1-1000范围的UID最好保留给系统用。
    • GID,也就是群组ID
    • 关于账号的一些说明信息
    • 账号的家目录,家目录就是你登陆系统后默认的那个目录
    • 账号使用的shell
  • /etc/shadow

    #由[:]来进行分割,这里一共分出来九个栏目
    root:!:15324:0:99999:7:::
    daemon:*:15259:0:99999:7:::
    bin:*:15259:0:99999:7:::
    letuknowit:$1$cPf/cIvr$sCws95uSip2ljTK052DDB.:15400:5:60:7:2:15490:
    • 账户名称(密码需要与账户对应的嘛)
    • 加密后的密码,如果这一栏的第一个字符为!或者*的话,说明这是一个不能登录的账户,从上面可以看出,ubuntu默认的就不启用root账户。
    • 最近改动密码的日期(这个是从1970年1月1日算起的总的天数)。
    • 密码不可被变更的天数:设置了这个值,则表示从变更密码的日期算起,多少天内无法再次修改密码,如果是0的话,则没有限制
    • 密码需要重新变更的天数:密码经常更换才能保证安全,为了提醒某些经常不更换密码的用户,可以设置一个天数,强制让用户更换密码,也就是说该用户的密码会在多少天后过期,如果为99999则没有限制
    • 密码过期预警天数:如果在5中设置了密码需要重新变更的天数,则会在密码过期的前多少天进行提醒,提示用户其密码将在多少天后过期
    • 密码过期的宽恕时间:如果在5中设置的日期过后,用户仍然没有修改密码,则该用户还可以继续使用的天数
    • 账号失效日期,过了这个日期账号就不能用了
    • 保留的

设置用户

  • 创建用户

    useradd XXXX
  • 设置用户密码

    passwd XXXX
  • 删除用户

    userdel XXXX
  • 切换用户

    su  XXXX

checksec参数

用来查看文件开启了什么保护(溢出保护)

RELRO:RELRO会有Partial RELRO和FULL RELRO,如果开启FULL RELRO,意味着我们无法修改got表
Stack:如果栈中开启Canary found,那么就不能用直接用溢出的方法覆盖栈中返回地址,而且要通过改写指针与局部变量、leak canary、overwrite canary的方法来绕过
NX:NX enabled如果这个保护开启就是意味着栈中数据没有执行权限,以前的经常用的call esp或者jmp esp的方法就不能使用,但是可以利用rop这种方法绕过
PIE:PIE enabled如果程序开启这个地址随机化选项就意味着程序每次运行的时候地址都会变化,而如果没有开PIE的话那么No PIE (0x400000),括号内的数据就是程序的基地址
FORTIFY:FORTIFY_SOURCE机制对格式化字符串有两个限制(1)包含%n的格式化字符串不能位于程序内存中的可写地址。(2)当使用位置参数时,必须使用范围内的所有参数。所以如果要使用%7$x,你必须同时使用1,2,3,4,5和6。

gdb基本命令

命令 简写 功能
file 装入想要调试的可执行文件.
kill k 终止正在调试的程序.
list l 列出产生执行文件的源代码的一部分.
next n 执行一行源代码但不进入函数内部.
step s 执行一行源代码而且进入函数内部.
continue c 继续执行程序,直至下一中断或者程序结束。
run r 执行当前被调试的程序.
quit q 终止 gdb.
watch 使你能监视一个变量的值而不管它何时被改变.
catch 设置捕捉点.
thread t 查看当前运行程序的线程信息.
break b 在代码里设置断点, 这将使程序执行到这里时被挂起.
make 使你能不退出 gdb 就可以重新产生可执行文件.
shell 使你能不离开 gdb 就执行 UNIX shell 命令.
print p 打印数据内容。
examine x 打印内存内容。
backtrace bt 查看函数调用栈的所有信息。

auditd命令

用来监控文件被什么进程修改

安装apt-get install auditd

  • auditd 是后台守护进程,负责监控记录
  • auditctl 配置规则的工具
  • auditsearch 搜索查看
  • aureport 根据监控记录生成报表
auditctl -w /var/spool/cron/crontabs/root -p awr -k asc0t6e
  • -w 指明要监控的文件
  • -p awrx 要监控的操作类型,append, write, read, execute
  • -k 给当前这条监控规则起个名字,方便搜索过滤

查看修改纪录:ausearch -i -k asc0t6e

type=PROCTITLE msg=audit(12/13/2019 15:13:28.750:99) : proctitle=crontab -l 
type=PATH msg=audit(12/13/2019 15:13:28.750:99) : item=0 name=crontabs/root inode=580 dev=fd:01 mode=file,600 ouid=root ogid=root rdev=00:00 nametype=NORMAL
type=CWD msg=audit(12/13/2019 15:13:28.750:99) : cwd=/var/spool/cron
type=SYSCALL msg=audit(12/13/2019 15:13:28.750:99) : arch=x86_64 syscall=open success=yes exit=3 a0=0x7ffe9bae73f0 a1=O_RDONLY a2=0x1b6 a3=0x0 items=1 ppid=10715 pid=10745 auid=root uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=pts9 ses=410442 comm=crontab exe=/usr/bin/crontab key=asc0t6e

上面命令的一些参数详解:

  • time : 审计时间。
  • name : 审计对象
  • cwd: 当前路径
  • syscall :相关的系统调用
  • auid : 审计用户ID
  • uidgid : 访问文件的用户ID和用户组ID
  • comm : 用户访问文件的命令
  • exe :上面命令的可执行文件路径

挂代理

在你的右键你的SSR->选项设置->打开允许来自局域网的连接

image-20191228122354113

接着在你的linux上添加如下命令

#ip为你开SSR那台电脑的内网IP
export ALL_PROXY=socks5://127.0.0.1:1080

文件的一些小操作

  • 隐藏文件

    Linux 下创建一个隐藏文件:touch .test.txt

    touch 命令可以创建一个文件,文件名前面加一个 点 就代表是隐藏文件

  • 查看隐藏文件

    #查看不到隐藏文件
    ls -l
    #可以查看隐藏文件
    ls -al
  • 文件属性查看

    lsattr  aaa.php
  • 锁定文件&解锁文件

    #锁定
    chattr +i aa.php
    #解锁
    chattr -i aa.php

进程的一些小操作

  • 进程隐藏libprocesshider

    github项目地址:https://github.com/gianlucaborello/libprocesshider

    利用 LD_PRELOAD 来实现系统函数的劫持,实现如下

    # 下载程序编译
    git clone https://github.com/gianlucaborello/libprocesshider.git
    cd libprocesshider/ && make
    # 移动文件到/usr/local/lib/目录下
    cp libprocesshider.so /usr/local/lib/
    # 把它加载到全局动态连接局
    echo /usr/local/lib/libprocesshider.so >> /etc/ld.so.preload
    #然后运行你的程序即可
  • 发现隐藏的进程

    unhide 是一个小巧的网络取证工具,能够发现那些借助rootkitLKM及其它技术隐藏的进程和TCP / UDP端口。这个工具在LinuxUNIX类,MS-Windows等操作系统下都可以工作。

    #下载地址:http://www.unhide-forensics.info/
    # 安装
    sudo apt-get install unhide
    # 使用
    unhide [options] test_list

主机异常检测

chkrootkit

#官网http://www.chkrootkit.org/
#下载
wget ftp://ftp.pangeia.com.br/pub/seg/pac/chkrootkit.tar.gz
#加压
tar -zxvf chkrootkit.tar.gz
cd chkrootkit
#运行
./chkrootkit

查看当前路径

可以查看当前所在位置

root@ascotbe:/home/user# pwd -P
/home/user

查看系统详细参数

apt install neofetch
#然后输入neofetch就能查看
root@iZbp19pfnyuhlghdkeobejZ:~# neofetch
_,met$$$$$gg. root@iZbp19pfnyuhlghdkeobejZ
,g$$$$$$$$$$$$$$$P. ----------------------------
,g$$P" """Y$$.". OS: Debian GNU/Linux 9.11 (stretch) x86_64
,$$P' `$$$. Model: Alibaba Cloud ECS pc-i440fx-2.1
',$$P ,ggs. `$$b: Kernel: 4.9.0-11-amd64
`d$$' ,$P"' . $$$ Uptime: 8 days, 2 hours, 21 minutes
$$P d$' , $$P Packages: 734
$$: $$. - ,d$$' Shell: bash 4.4.12
$$; Y$b._ _,d$P' Theme: Adwaita [GTK3]
Y$$. `.`"Y$$$$P"' Icons: Adwaita [GTK3]
`$$b "-.__ CPU: Intel Xeon E5-2682 v4 (1) @ 2.4GHz
`Y$$ GPU: Cirrus Logic GD 5446
`Y$$. Memory: 551MB / 2004MB
`$$b. ​
`Y$$b. ████████████████████████
`"Y$b._ ​
`"""

top命令详细讲解

  • 参数含义

    top - 01:06:48 up  1:22,  1 user,  load average: 0.06, 0.60, 0.48
    Tasks: 29 total, 1 running, 28 sleeping, 0 stopped, 0 zombie
    Cpu(s): 0.3% us, 1.0% sy, 0.0% ni, 98.7% id, 0.0% wa, 0.0% hi, 0.0% si
    Mem: 191272k total, 173656k used, 17616k free, 22052k buffers
    Swap: 192772k total, 0k used, 192772k free, 123988k cached

    PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
    root 16 0 7976 2456 1980 S 0.7 1.3 0:11.03 sshd
    root 16 0 2128 980 796 R 0.7 0.5 0:02.72 top
    root 16 0 1992 632 544 S 0.0 0.3 0:00.90 init
    root 34 19 0 0 0 S 0.0 0.0 0:00.00 ksoftirqd/0
    root RT 0 0 0 0 S 0.0 0.0 0:00.00 watchdog/0

    统计信息区前五行是系统整体的统计信息。第一行是任务队列信息,同 uptime 命令的执行结果。其内容如下:

    01:06:48    当前时间
    up 1:22 系统运行时间,格式为时:分
    1 user 当前登录用户数
    load average: 0.06, 0.60, 0.48 系统负载,即任务队列的平均长度。三个数值分别为 1分钟、5分钟、15分钟前到现在的平均值。

    第二、三行为进程和CPU的信息。当有多个CPU时,这些内容可能会超过两行。内容如下:

    total 进程总数
    running 正在运行的进程数
    sleeping 睡眠的进程数
    stopped 停止的进程数
    zombie 僵尸进程数
    Cpu(s):
    0.3% us 用户空间占用CPU百分比
    1.0% sy 内核空间占用CPU百分比
    0.0% ni 用户进程空间内改变过优先级的进程占用CPU百分比
    98.7% id 空闲CPU百分比
    0.0% wa 等待输入输出的CPU时间百分比
    0.0%hi:硬件CPU中断占用百分比
    0.0%si:软中断占用百分比
    0.0%st:虚拟机占用百分比

    最后两行为内存信息。内容如下:

    Mem:
    191272k total 物理内存总量
    173656k used 使用的物理内存总量
    17616k free 空闲内存总量
    22052k buffers 用作内核缓存的内存量
    Swap:
    192772k total 交换区总量
    0k used 使用的交换区总量
    192772k free 空闲交换区总量
    123988k cached 缓冲的交换区总量,内存中的内容被换出到交换区,而后又被换入到内存,但使用过的交换区尚未被覆盖,该数值即为这些内容已存在于内存中的交换区的大小,相应的内存再次被换出时可不必再对交换区写入。

    进程信息区统计信息区域的下方显示了各个进程的详细信息。首先来认识一下各列的含义。

    序号  列名    含义
    a PID 进程id
    b PPID 父进程id
    c RUSER Real user name
    d UID 进程所有者的用户id
    e USER 进程所有者的用户名
    f GROUP 进程所有者的组名
    g TTY 启动进程的终端名。不是从终端启动的进程则显示为 ?
    h PR 优先级
    i NI nice值。负值表示高优先级,正值表示低优先级
    j P 最后使用的CPU,仅在多CPU环境下有意义
    k %CPU 上次更新到现在的CPU时间占用百分比
    l TIME 进程使用的CPU时间总计,单位秒
    m TIME+ 进程使用的CPU时间总计,单位1/100秒
    n %MEM 进程使用的物理内存百分比
    o VIRT 进程使用的虚拟内存总量,单位kb。VIRT=SWAP+RES
    p SWAP 进程使用的虚拟内存中,被换出的大小,单位kb。
    q RES 进程使用的、未被换出的物理内存大小,单位kb。RES=CODE+DATA
    r CODE 可执行代码占用的物理内存大小,单位kb
    s DATA 可执行代码以外的部分(数据段+栈)占用的物理内存大小,单位kb
    t SHR 共享内存大小,单位kb
    u nFLT 页面错误次数
    v nDRT 最后一次写入到现在,被修改过的页面数。
    w S 进程状态(D=不可中断的睡眠状态,R=运行,S=睡眠,T=跟踪/停止,Z=僵尸进程)
    x COMMAND 命令名/命令行
    y WCHAN 若该进程在睡眠,则显示睡眠中的系统函数名
    z Flags 任务标志,参考 sched.h

增大ELF文件体积

文件末尾追加数据

这种方式实现很简单,如下

[root@instance-fj5pftdp y]# echo 1111 >> ./id
[root@instance-fj5pftdp y]# ./id
uid=0(root) gid=0(root) 组=0(root)

关键是这样修改后的文件,还能正常执行。

稀疏文件

"稀疏文件"的"文件大小"和实际占用磁盘空间是不一致的,比如:

[root@instance-fj5pftdp y]# ll -h id
-rwxr-xr-x 1 root root 10T 9月 6 20:03 id
[root@instance-fj5pftdp y]# du -sh id
40K id

从上面命令可以看到:"文件大小"是10T,但实际数据只占用40K的磁盘大小。

对于原理感兴趣的读者,可以参考 深度剖析 Linux cp 的秘密 这篇文章。

可以利用fallocate、truncate命令,来修改成"稀疏文件"。

使用起来也很简单,以truncate举例:

[root@instance-fj5pftdp y]# ls -alh id
-rwxr-xr-x 1 root root 37K 9月 5 20:18 id
[root@instance-fj5pftdp y]# time truncate -s 10T id // 将id程序稀疏成10T大小

real 0m0.007s
user 0m0.000s
sys 0m0.007s
[root@instance-fj5pftdp y]# ls -alh id
-rwxr-xr-x 1 root root 10T 9月 5 20:02 id // 文件大小已经变成10T
[root@instance-fj5pftdp y]# ./id
uid=0(root) gid=0(root) 组=0(root)

这种方式修改文件有两个特点:

文件改动非常快,上面的例子中将id文件大小扩大到"10T"只用了1s不到

文件大小最大可以是10T以上,但不需要本地磁盘空间真的有10T

当你想下载或者读这个文件(比如cat)时,却是会有实实在在的10T流量。10T流量,按照"10M/s"的速度下载,也需要下载291个小时。

修改inode元数据

inode元数据包含了文件大小信息,而inode元数据也是存储在磁盘扇区中的,所以应该可以通过修改inode元数据来"伪造"文件大小。

其实不光大小信息,inode元数据中还包括 文件是否删除、创建时间、修改时间、访问时间 等信息,所以这些都可以被伪造。

可以通过stat命令查看inode元数据:

[root@instance-fj5pftdp y]# stat id
文件:"id"
大小:37400 块:80 IO 块:4096 普通文件
设备:fd01h/64769d Inode:171252 硬链接:1
权限:(0755/-rwxr-xr-x) Uid:( 0/ root) Gid:( 0/ root)
最近访问:2021-09-06 20:27:26.224913458 +0800
最近更改:2021-09-06 20:27:26.218913032 +0800
最近改动:2021-09-06 20:27:26.224913458 +0800
创建时间:-

修改"inode元数据" ,利用debugfs命令,如下:

[root@instance-fj5pftdp ~]# debugfs -w /dev/vda1
debugfs: mi /tmp/y/id
Mode [0100755]
User ID [0]
Group ID [0]
Size [37400] 100000 // 这里修改文件大小为100000
Creation time [1630929039]
...
debugfs: quit
[root@instance-fj5pftdp ~]# ll /tmp/y/id
-rwxr-xr-x 1 root root 37400 9月 6 19:50 /tmp/y/id
[root@instance-fj5pftdp ~]# echo 3 > /proc/sys/vm/drop_caches // 清理inode缓存后,修改才生效
[root@instance-fj5pftdp ~]# ll /tmp/y/id
-rwxr-xr-x 1 root root 100000 9月 6 19:50 /tmp/y/id // 文件大小变成了100000
[root@instance-fj5pftdp ~]# /tmp/y/id
uid=0(root) gid=0(root) 组=0(root)

在测试过程中,需要读者注意的是:

因为会对磁盘数据做写操作,所以最好找一个没数据的机器做测试

记得清理inode缓存

测试时如果使用文件当作设备,在挂载文件系统时去修改文件大小 会不生效。原因未知

向elf文件节中添加垃圾数据

elf文件中包含很多的,比如:

.text存放代码

.data存放初始化的全局变量和静态变量

可以向elf的节(比如.data、.text、.bss等)中写入垃圾数据,而不影响程序的正常运行。

这种方式和其他三种方式的区别在于:因为可以删掉没用的节,所以就很容易就把"其他三种方式"修改的elf给还原回来。

比如strip后,文件大小就还原了

[root@instance-fj5pftdp y]# ll -h id
-rwxr-xr-x 1 root root 10T 9月 6 20:03 id
[root@instance-fj5pftdp y]# strip id
[root@instance-fj5pftdp y]# ll -h id
-rwxr-xr-x 1 root root 37K 9月 6 20:27 id

内核学习

软连接和硬连接的区别

为了解释清楚,我们首先在自己的一个工作目录下创建一个文件,然后对这个文件进行链接的创建:

[ascotbe@linux]$ touch myfile && echo "This is a plain text file." > myfile
[ascotbe@linux]$ cat myfile
This is a plain text file.

现在我们创建了一个普通地不能再普通的文件了。然后我们对它创建一个硬链接,并查看一下当前目录:

[ascotbe@linux]$ ln myfile hard
[ascotbe@linux]$ ls -li

25869085 -rw-r--r-- 2 unixzii staff 27 7 8 17:39 hard
25869085 -rw-r--r-- 2 unixzii staff 27 7 8 17:39 myfile

ls 结果的最左边一列,是文件的 inode 值,你可以简单把它想成 C 语言中的指针。它指向了物理硬盘的一个区块,事实上文件系统会维护一个引用计数,只要有文件指向这个区块,它就不会从硬盘上消失。

你也看到了,这两个文件就如同一个文件一样,inode 值相同,都指向同一个区块。

然后我们修改一下刚才创建的 hard 链接文件:

[ascotbe@linux]$ echo "New line" >> hard
[ascotbe@linux]$ cat myfile

This is a plain text file.
New line

可以看到,这两个文件果真就是一个文件。
下面我们看看软链接(也就是符号链接)和它有什么区别。

[ascotbe@linux]$ ln -s myfile soft
[ascotbe@linux]$ ls -li

25869085 -rw-r--r-- 2 unixzii staff 36 7 8 17:45 hard
25869085 -rw-r--r-- 2 unixzii staff 36 7 8 17:45 myfile
25869216 lrwxr-xr-x 1 unixzii staff 6 7 8 17:47 soft -> myfile

诶,你会发现,这个软链接的 inode 竟然不一样啊,并且它的文件属性上也有一个 l 的 flag,这就说明它与之前我们创建的两个文件根本不是一个类型。

下面我们试着删除 myfile 文件,然后分别输出软硬链接的文件内容:

[ascotbe@linux]$  rm myfile
[ascotbe@linux]$ cat hard

This is a plain text file.
New line
[ascotbe@linux]$ cat soft

cat: soft: No such file or directory
[ascotbe@linux]$ cat soft

cat: soft: No such file or directory

之前的硬链接没有丝毫地影响,因为它 inode 所指向的区块由于有一个硬链接在指向它,所以这个区块仍然有效,并且可以访问到。
然而软链接的 inode 所指向的内容实际上是保存了一个绝对路径,当用户访问这个文件时,系统会自动将其替换成其所指的文件路径,然而这个文件已经被删除了,所以自然就会显示无法找到该文件了。

接着我们在软连接的文件中写入文件,被删除的文件就会回来了!!!而硬连接并不会出现这样

[ascotbe@linux]$ echo "Something" >> soft
[ascotbe@linux]$ ls

hard myfile soft
  • 硬链接: 与普通文件没什么不同,inode 都指向同一个文件在硬盘中的区块,删除一个指针不会真正删除文件,只有把所有的指针都删除才会真正删除文件。
  • 软链接: 保存了其代表的文件的绝对路径,是另外一种文件,在硬盘上有独立的区块,访问时替换自身路径。

参考文章

https://mp.weixin.qq.com/s/WQeOfZtyKndbDebe66-V_g