suterusu的文件、进程、端口隐藏代码简解,位于main.c
文件结构体和文件操作结构体推荐看《Linux内核设计与实现》去初步了解,进程隐藏实际上是文件隐藏的复用
1 |
|
拿到/proc
和/
目录的文件结构体中readdir
函数指针
1 |
|
1 |
|
1 |
|
文件隐藏有个小bug,strcmp不含长度比较,直接使用会出错,能看见下图中字符指针存在脏数据,故字符串比较需要带上长度
要隐藏连接和端口,就需要对netstat的底层调用有所了解
这里使用strace来查看函数调用,strace netstat -antu
,结果如下
/proc/net/tcp
文件提供了tcp的连接信息,是由net/ipv4/tcp_ipv4.c
中的tcp4_seq_show()
实现信息打印的 reftcp4_seq_show
就是seq_operations
中的show
函数 ref1 |
|
另外如果要hook另一种网络连接查看方式ss,其系统调用链和netstat不同,用strace ss -antu
查看后发现需要hook的函数是recvmsg
,后续会尝试实现在自己的demo中
再来看具体的hook函数
1 |
|
思路是,先调用真的show
向seq
中写入一条记录,然后检查写入的内容中是否有:your_port_number
这个字符串,如果有,就把seq->count
这个记录缓冲区已经使用的字节数减去一条记录的长度TMPSZ
相当于之前写入的无效了;如果没有,就正常放行。
ref: Linux Rootkit实验|0204 Rootkit基本功能之隐藏端口
1 |
|
通过hook原生api dev_get_flags
,将混杂标志位隐藏,混杂模式被rootkit用来进行网络流量嗅探,不过其实这样很容易被发现,只要管理员调整混杂模式或使用tcpdump抓包就会被发现
suterusu的系统调用函数hook部分代码解析,位于util.c
想要hook内核函数,我们必须先得到syscall表,通过syscall表找到各个函数。这里使用暴搜(获取sys_call_table还有很多别的手段 此处占坑),从sys_close
向下查找,直到syscall_table[__NR_close] == sys_close
,这时候的syscall_table即为全局符号表。
1 |
|
找到syscall表后我们就可以用宏来查找对应的函数指针,比如syscall_table[__NR_write]
,其中__NR_write
就是系统写函数对应的下标。
hook函数即是将函数指针指向的内容进行改变,同时新函数与原始函数保持相同的参数列表。系统依然会调用函数指针,但每次都会执行的都是我们替换上去的新函数,在新函数内完成自己想要的动作之后,再回调原始函数来完成系统原本的操作。
这里hook函数使用了函数蹦床技术,因为如果直接通过修改函数指针,比如symbol_table[__NR_write] = our_new_pointer
,这样直接将原来的系统函数指针替换成我们的新函数指针很容易被检测到。于是采用更改系统函数指针所指向内存的前几个字节,跳转到我们的新函数上来达到劫持效果。
1 |
|
1 |
|
写保护的开启关闭
理清了上述hook的流程后,其实还少了几步关键细节没说。如果你想直接对sys_read赋值,sorry 系统有对应的保护机制,防止你做此高危操作,这时候需要关闭写保护。
WP位
是控制只读区域是否可写。置1时,只读区域只能被读出;置0时,则CPU可以在任意位置进行写入new_func
写入sys_read
指向的只读区,必须先将cr0
的WP
置0Linux提供了读写cr0
的接口
unsigned long read_cr0()
write_cr0(unsigned long)
1 |
|
将上述几个关键点写成代码
1 |
|
找到符号表后想要完成hook动作,同时在后期还要实现对系统函数的恢复、重置、清除,那么我们还需要用一个结构体来保存系统函数位置,以及位置里面的值,为了将此结构体以链表的形式进行管理,我们还需要添加侵入式链表元素,结构体如下。
1 |
|
suterusu是一款跨多个Linux平台的rootkit,打入目标系统后能够完成文件隐藏、进程隐藏、端口隐藏、目录隐藏、文件下载、控制系统读写、远程交互等功能,是初学rootkit的必看材料,附上作者对suterusu的分析blog
除去主模块之外,还可以选择性编译6个扩展模块
1 |
|
主要功能:
1 |
|
1 |
|
主要功能:函数挂入消息通知队列,当有新模块打入时,将新模块的init和exit函数替换为我们的空函数,达到防止后续模块加入的效果
1 |
|
1 |
|
主要功能:维护全局工作队列,将文件下载任务添入队列,文件下载后将文件权限改为777,配合icmp模块使用
get_fs()
,set_fs(mm_segment_t)
,get_ds()
,内核以此来对用户空间的文件进行操作1 |
|
主要功能:锁屏和记录按键
这里的密码很有趣,音量升键 上箭头 上箭头 音量降键 ??键 ??键
x 2
1 |
|
1 |
|
主要功能:通过ioctl和mod进行交互,选择不同的接口,传入对应的参数
1 |
|
1 |
|
主要功能:通过netfilter判断操作系统接收到的icmp报文,若icmp报文的magic字段同内置相符,则调用dlexec将对应ip和port挂入下载队列,完成文件传输和执行
http://staff.ustc.edu.cn/~james/linux/netfilter-4.html
1 |
|
1 |
|
grep sed awk的基本使用
Global search REgular expression and Print out the line
文本搜索工具,根据用户指定的“模式(过滤条件)“对目标文本进行逐行过滤
由正则表达式的元字符
和文本字符
所编写出的过滤条件
1 |
|
BRE基本正则和ERE扩展正则
1 |
|
-E
)字符 | 作用 |
---|---|
+ | 1或n次 |
[1-5]+ | 字符1或n词(同上) |
? | 0或者1 |
| | 或关系 |
() | 分组(含前向引用等用法) |
a{n,m}类 |
1 |
|
Stream Editor(字符流编辑器),流编辑器
结合正则对文本快速增删改查,主要功能为过滤
和取行
1 |
|
参数 | 作用 |
---|---|
-n | 取消默认sed输出,常和p一起用 |
-i | 直接将修改结果写入文件。若不用-i,则sed修改的是内存数据 |
-e | 多次编辑,不需要管道符了 |
-r | 支持正则扩展 |
sed的内置命令字符
用于对文件进行不同的操作功能,如对文件增删改查
内置字符 | 作用 |
---|---|
a | append,对文本追加,在指定行后面添加一或多行文本 |
d | delete,删除匹配行 |
i | insert,插入文本,在指定行前添加一或多行 |
p | print,打印匹配行的内容,常与-n搭配 |
c | 替换,c后接字符串,可以取代n1,n2之间内容 |
s/正则/替换内容/g | 匹配正则内容,然后替换内容,g代表全局匹配 |
范围 | 解释 |
---|---|
空地址 | 全文处理 |
单地址 | 指定文件的某一行 |
/pattern/ | 被匹配到的每一行 |
范围区间 | 10,20 10到20行 ,10,+5第10行向下5行 ,/pattern1/,/pattern2/ |
步长 | 1~2 ,表示1、3、5、7、9、奇数行,2~2 两个步长,表示2、4、6、8、10、偶数行 |
平常用到:
1 |
|
1 |
|
具有文本格式化能力,同时也是一门简单的编程语言,具有变量、数组、判断、循环等功能
1 |
|
1 |
|
打印文本的第一列(默认用空格分隔)
$NF
表示当前分割最后一列,倒数第二列$(NF-1)
参数 | 作用 |
---|---|
F | 指定分隔符 |
v | 定义 or 修改一个awk内部变量 |
f | 从脚本中读取awk命令 |
更多选项详见手册 |
内置变量 | 含义 |
---|---|
$n | 当前第n个字段 |
$0 | 整行 |
FS | 字段分隔符,默认空格 |
NF | 当前一共多少个字段 |
NR | 当前记录数,行数 |
一次输出多列
1 |
|
自定义输出内容
awk必须外层单引号,内层双引号
内置变量$1、$2
都不能添加双引号,否则会识别为文本,尽量别加引号
1 |
|
输出整行信息
1 |
|
显示文件第5到7行
1 |
|
显示行号和每行数据
1 |
|
awk分隔符有两种
内置变量
$
,但时其代表一个数字时加上$
,即可表示$number1 |
|
下面是详细版本的内置变量
内置变量 | 作用 |
---|---|
FS | 输入字段分隔符,默认空格 |
OFS | 输出字段分隔符,默认空格 |
RS | 输入资料分隔符(输入换行符),指定输入时的换行符 |
ORS | 输出记录分隔符(输出换行符),输出时用指定符号代替换行符 |
NF | number of field,当前行的字段个数 |
NR | 行号 |
FNR | 各文件分别计数的行号 |
FILENAME | 当前文件名 |
ARGC | 命令行参数个数 |
ARGV | 数组,命令行给定的参数 |
分隔符修改
1 |
|
修改输出符
1 |
|
修改RS
1 |
|
修改ORS
回车换行符
,即ORS默认为回车换行1 |
|
RS ORS一起用
1 |
|
ARGV
1 |
|
自定义
1 |
|
printf格式化
-
左对齐空模式
关系运算符模式
关系运算符 | 作用 | 示例 |
---|---|---|
<、<=、==、!=、>=、> | 比较 | x!=y |
~ | 匹配正则 | x~/regex/ |
!~ | 不匹配正则 | x!~/regex/ |
1 |
|
本文将以问题驱动,算是一篇trouble shooting,以解决问题为导向,故不会所有方面都提及。主要讲解我对问题的了解、思考和在实际场景中的工程化解决方法。更深层次的bpf语句使用可能会在下一篇(如果我能研究透彻的话~)
去年在suricata中实现了报文的过滤,主要的方式就是在驱动层获取报文后利用libpcap中的几个接口,以标准bpf的形式对报文进行匹配过滤,类似于很多防火墙提供的功能。
今年收到反馈的问题,在某客户环境下无法完成过滤,我远程操作后发现手动在引擎播放攻击流量可以完成过滤,但是在外网实时进行模拟攻击却无法过滤。
产品bpf过滤功能有两种模式,一是简易模式,用户可以配置源目的IP、port,tcp、udp、any协议,vlan id
;二是专业模式,完全由用户编写bpf语句。
下面的报文均为测试构造的报文
标准bpf语法,标准bpf语法和wireshark的filter栏中语法不同,前者是后者的子集。wireshark算是将协议变量都解析出来再提供比标准bpf更丰富的搜索,标准bpf更多还是通过偏移来完成过滤。
常用的关键字(原语)
1 |
|
下面我们主要用tcpdump和对应的报文来完成bpf的测试。-r
读取报文,同时要判断bpf解析对不对我们会用到-d
选项,来查看字节码。
先给个示例介绍基本分析方式,测试报文:test_bpf.pcap
过滤源IP:10.51.15.205,目的IP:222.186.160.66
tcpdump -r test_bpf.pcap "ip src host 10.51.15.205 and ip dst host 222.186.160.66"
能看到使用这条bpf语句能过滤出330帧报文,下面我们用-d
选项查看字节码
tcpdump -d "ip src host 10.51.15.205 and ip dst host 222.186.160.66"
1 |
|
通过字节码能够看见bpf经过解释后生成的逻辑语句,帮助我们进一步判断自己的bpf是否编写正确。
偏移默认从ether协议开始。ldh [12]
是从ether offset 12
读取两个字节,jeq
同0x800
比较(报文是否为IP协议),相同则跳转到2步骤,不同则跳转到7步骤。如果是IP协议,进入2步骤ld [26]
,在ether offset 26
读取一个字(IP src host)同10.51.15.205
的16进制数比较,其后同理。可看到我们的bpf是合理的,所以能够过滤对应的报文。
字节码中的部分关键字含义 [所有关键字资料]
1 |
|
由于在引擎上对报文重放能够过滤,而在外网对客户模拟渗透无法达到过滤效果,就决定在客户现场进行实时抓包,拿到报文之后再进行报文分析。
测试报文:single_vlan.pcap(模拟用,非用户现场报文)
拿到报文之后就发现了报文中存在vlan,这在用户环境很常见。我们也支持vlan配置,不过每次都需要配置vlan id,这种必须要用户对自己环境下的流量进行分析后才能编写bpf语句。
分析完用户报文之后,在web页面配置上vlan id下发bpf语句到引擎,每条独立的bpf语句用or
来进行连接,保证过滤逻辑。生成的bpf语句如下:
((vlan 2000) and (ip src host 10.216.143.250)) or ((vlan 2000) and (ip src host 101.35.124.69))
再来看一下我们测试报文,一共15个分组
尝试过滤
发现仅过滤出13个报文,抓到了所有250->69的包,但缺少了两个69->250的包,可以判断在现场也是出现了这样的问题,下面分析字节码:
tcpdump -d "((vlan 2000) and (ip src host 10.216.143.250)) or ((vlan 2000) and (ip src host 101.35.124.69))"
1 |
|
从字节码中可以看到,在第一段对于src host的判断中在最终的IP判断后直接跳转结束。这样我们第二段的bpf永远也走不到。经过尝试,调换一二段bpf顺序,靠前的bpf语句段会被过滤。但为什么会这样?
从逻辑上看,我们下发的bpf语句使用or
来连接,是准确无误的,在各种编程语言中都能正确地表达含义,但这里最终效果却表明bpf的语义分析似乎不同。于是我的怀疑点转到了括号的优先级上。
下面的bpf测试用例用于判断括号是否无效
tcpdump -d "ip src host 1.1.1.1 and ip dst host 2.2.2.2 or ip dst host 3.3.3.3"
1 |
|
tcpdump -d "ip src host 1.1.1.1 and (ip dst host 2.2.2.2 or ip src host 3.3.3.3)"
1 |
|
tcpdump -d "ip src host 1.1.1.1 and ip dst 2.2.2.2 or ip src host 1.1.1.1 and ip dst host 3.3.3.3"
1 |
|
从上面的测试用例看,普通情况下括号并没有失效,而且bpf语义分析后会对相同部分进行简单的合并
这时候我们减去部分多余括号,带入vlan关键字再次进行测试
tcpdump -d "(vlan and ip src host 10.216.143.250) or (vlan and ip src host 101.35.124.69)"
1 |
|
结果还是没变,这种情况下依然没有达到想要的效果,碰到vlan关键字我们的bpf语句都不对劲起来。又经过一番长时间的资料搜索,发现了两篇很有帮助的文章
[1] Mixed VLAN tags and BPF syntax
尤其第二篇,和我碰到的问题几乎相同,它里面给出的解法是自行编写bpf以vlan头来过滤,(ether[12:2]==0x8100) and (ether[14:2]&4095==7 orether[14:2]&4095==10)
。但这样给用户的操作难度太大,对bpf没有研究基本写不出来而且很容易写错。
考虑到前面所有的因素,发现一个规律,当vlan存在时,在一旦bpf过滤开始进入一个and
段中并匹配上第一个关键字即vlan
,那么就会不断匹配下去而不能进入后续的and
段,其中有哪一特征不相同就会判断为过滤失败。此时bpf不会进行语义合并操作。
1 |
|
只要报文匹配上了vlan那么后面只会匹配B再匹配D,第二段不会再进入。
那么我们面对vlan这种情况,想到的办法就是用户操作时在下发至引擎的BPF语句直接合并,即:
1 |
|
合并为
1 |
|
tcpdump -d "(vlan 2000) and ((ip src host 10.216.143.250) or (ip src host 101.35.124.69))"
1 |
|
用此方法最终解决了我们当前的问题
当前问题虽然解决了,但是如果给用户配置vlan id
的机会,那么我们在后端合并操作的工作量就会变得大了而且没有必要。这时候考虑到开发量、bpf学习成本以及客户可用性,我们将简易模式中的vlan id
修改为下拉框的形式,只能选择0、1、2三层vlan,向用户隐藏vlan id
,仅提供层数选择。这样既方便后端按照0、1、2三层vlan对bpf语句进行合并,对用户来说也减小了学习难度提升了易用性。
1 |
|
ip host x.x.x.x
的形式处理,不能使用src
、dst
两个关键字[4] tell tcpdump to filter mixed tagged and untagged VLAN (IEEE 802.1Q) traffic
[5] bpf-the-forgotten-bytecode
[8] Dive into BPF: a list of reading material
[9] BPF for IP or VLAN Traffic
]]>tsh是一款轻量级远程shell工具,可在多个平台上编译运行,被集成在较为完善的Linux rootkit Reptile 中
其实现了文件传输和真正的交互shell,交互全程用aes和sha1加密
代码量比socat小,但很精巧,适合初级红队开发者进行学习
本篇的关键在 tty和pty的设置与使用,其余涉及一点点信号、网络、多进程操作、IO模型会简略提一下
1 |
|
为了保证加密传输,作者将加密逻辑抽象出来形成 pel.[ch](packet encrypt layer)
,对外提供4个接口,方便主逻辑调用
1 |
|
通过指定参数,支持三种基本功能
交互shell
获取文件
传输文件
-s
设置了密码,错误则直接认证失败tshd_server主流程
&
符号令进程后台运行1 |
|
alarm(3)
的作用是给当前进程设置一个3秒的时钟,如果pel_server_init
处理太慢,则操作系统会发送一个SIGALRM信号中断此进程,达到合理关闭该进程的效果。alarm(0)
的作用是 如果流程正常进行,则取消闹钟1 |
|
1 |
|
二者为主从关系,pty (master),tty (slave)
伪终端的出现是因为一些面向终端应用的输入(或输出)不再直接来自(或去往)实际终端
伪终端是一对虚拟的字符设备,linux内核使用一种符合tty线规程(line discipline)的双向管道连接伪终端的主从设备
主设备上的任何写入操作都会反映到从设备上,反之亦然,从设备上的应用进程可以像使用传统终端一样读取来自主设备上应用程序的输入,以及向主设备应用输出信息
伪终端从设备应用通常是主设备应用的子进程,主应用打开一对伪终端并fork一个子进程,然后子进程打开并使用从设备,伪终端应用的实现模型可用下图表示
Everything is file
宏的使用,做到跨平台,Linux系统编程基本方法
主动创建孤儿进程,避免出现僵尸进程
tty和pty的使用做到了真正的交互shell
pty.spawn("/bin/bash")
交互shell其实依然为某种程度哑shell,无法完成某些高交互进程(如:vim)的使用,需要进一步升级设置窗口大小,控制返回值窗口
存在bug,输入./tshd asdf
后台会一直创建进程,最终跑死机器
[2] What’s the difference between various $TERM variables?
[3] 理解 Linux 中的 tty、pty、pts、console、terminal
[4] Why do I need to run “/bin/bash –login”
]]>前提:gcc-linaro-5.3.1-2016.05-i686_aarch64-linux-gnu编译链配置完成,CFLAGS、LDFLAGS等关键环境变量已经导入/etc/profile,如下图
Linux localhost.localdomain 4.18.0-193.28.1.el7.aarch64 #1 SMP Wed Oct 21 16:25:35 UTC 2020 aarch64 aarch64 aarch64 GNU/Linux
我们需要用到的编译选项
1 |
|
arm版本gcc的编译选项
对照arm环境中的共享对象,我们找到交叉编译环境下的相同共享对象,指定对应的依赖路径,保证无误
1 |
|
按照上述configure选项,我们生成了对应的makefile,最下面的warning能判断,我们没有将openssl和libssh2加入(用不到就不加)
执行make,开始编译报如下错误
1 |
|
发现是路径指定出错,configure生成的makefile会找到我们给出路径的include目录,下面给出修改
1 |
|
继续make,成功编译
最终我们的编译选项
1 |
|
成功编译安装
]]>第二篇依然从简单入手,Stitch C2框架(小pupy) 主要使用python2实现,支持Win、Linux、Mac三种平台
1 |
|
linux shell
win shell
osx shell
上述的三个类功能基本相同,都是按照以下三个部分来进行编码
do section
complete section
help section
下面是作者编写的PyLib,主要就是一个功能函数的集合,对stitch lib提供支持。其中主要的做法有两种,一种是使用系统shell或者python原生的ctypes、os、sys、subprocess、_winreg等库完成系统调用实现功能,另一种是使用powershell进行命令处理。
1 |
|
由于最近写c2感觉自己有闭门造车之势,于是读了一遍AHXR/ghost的源码,发现自己很多想法还不成熟,打算先把周遭的c2读一遍,开一个《安全工具月月读》专题,提升一下自己的眼界。我会尽量把blog写得简单易懂,有问题的地方持续改进
作者把很多函数实现都写在头文件中,这操作让代码混乱,不过可以方便引用,c++中的hpp就是这样
1 |
|
数据结构并不复杂,大多数都是直接全局声明的数值和字符串,这里仅介绍结构体和类
struct _clientData
是zombie的主要结构体
1 |
|
class gui
是server的界面类,继承了windows系统表格基类
1 |
|
对上面的GUI编程暂时不是很了解,就是把参数填到对应的入口中,比如程序图标注册、双击回调函数注册,在构造函数那里还能进行一些扩展操作。
其中采用vector维护全局clientData集合
std::vector < GHOSTLIB > client_data;
其中存在两个函数接口及其实现
1 |
|
原理很简单,密码和明文下标相对应转换,通信全程用这种方法加解密
1 |
|
1 |
|
几个要点:
server端的主要逻辑在console.h中
大体的逻辑结构:先设置端口、超时时间,保存刚才的配置,然后在一个while(1)循环内读取命令or选项
代码略丑就不放出来,单纯通过堆砌while和SwitchCase完成逻辑,下面是zombie和server的执行效果
下面用简单的伪代码演示server逻辑
1 |
|
#pragma once
:让文件编译一次,防止多次引入,有别于#ifndef
[8]#pragma comment (lib, "lib_name")
:链接对应的库,这样就不用再手动设置工程settings#pragma region(endregion)
:pragma region (endregion) 是一个Visio Studio Code Editor中的命令,来定义可以扩展和收缩的代码区域的开头和结尾,可以用来收缩或者展开一段代码。cin.ignore()
:吃掉一个字符,比如最后的\n
,防止干扰下一次输入^
并非c#扩展,而是c++/cli中的语法,c++/cli是标准c++的超集,该语法拥有垃圾回收特性缺乏经验,学习之
1 |
|
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 5.9p1 Debian 5ubuntu1.8 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|1024 66:8c:c0:f2:85:7c:6c:c0:f6:ab:7d:48:04:81:c2:d4 (DSA)
|2048 ba:86:f5:ee:cc:83:df:a6:3f:fd:c1:34:bb:7e:62:ab (RSA)
|_256 a1:6c:fa:18:da:57:1d:33:2c:52:e4:ec:97:e2:9e:af (ECDSA)
80/tcp open http lighttpd 1.4.28
|_http-server-header: lighttpd/1.4.28
|_http-title: Site doesn’t have a title (text/html).
MAC Address: 00:0C:29:CE:AB:B8 (VMware)
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose
Running: Linux 3.X|4.X
OS CPE: cpe:/o:linux:linux_kernel:3 cpe:/o:linux:linux_kernel:4
OS details: Linux 3.10 - 4.11, Linux 3.16 - 4.6, Linux 3.2 - 4.9, Linux 4.4
Network Distance: 1 hop
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernelTRACEROUTE
HOP RTT ADDRESS
1 0.98 ms 192.168.206.151
两个端口开放80和22
访问一下80,就一张meme图
查看源码,也没有东西,使用dirb和nikto扫描端口
出现一个test
文件夹,浏览器访问
得知是lighttpd 1.4.28
版本,查看web指纹
没有建设性资料,再于其基础上dirb路径爆破,依然无果,80端口暂放
hydra进行ssh爆破
1 |
|
均未成功,看来这里存在知识盲区
一番查询后得知,可用curl来服务器探查支持的HTTP方法,就对于仅有的两个页面进行探查
1 |
|
/test/
路径下支持多种方法
以前只在图解HTTP中听说过,从来没有实际操作过HTTP方法。使用curl直接采用PUT方法,尝试将后门放入服务器
1 |
|
可以看见在test
页面中出现了t.php
用蚁剑连接,连接超时!
一句话中没有中文字符,同时也测试了好几个其他免杀木马,均连接失败,随手传了个phpinfo却能执行
经过验证,后台代码可以执行,但是无法接收,这样也好说,既然传不了那我就直接执行,结果也会失败。
如上图,能看见是服务端错误
这种一直断连的场景存在waf的可能性很高,于是使用nmap
、wafw00f
、sqlmap
1 |
|
以上的waf探测没有下文
test
下的x.php
,使用burpsuite进行拦截,直接在bp中对HTTP报文进行修改,将一句话写入
尝试访问,成了!
我想看看之前为什么会出错,所以继续写入指令cat%20x.php
,然后用bp拦截
上图可见,我们用curl写入的webshell已经不成形了,后续再次写入webshell并cat查看,发现$_GET['pass']
变成了['pass']
,带有$
的部分都被删去了一些,不用说了,看下面的解析。
问题的来龙去脉(Kioptrix2014也遇到过)
php一句话的两种写法
"<?php system($_GET['pass']); ?>"
'<?php system($_GET["pass"]); ?>'
第一种:双引号套单引号
$号会被解析,需要转义
第二种:单引号套双引号
$号不会被解析,无需转义
找到kali中的php-reverse-shell.php
文件,调整ip为192.168.206.142
,port为4444
,复制全部代码,粘贴到bp中发送。
kali中nc监听,浏览器中点击reverse-webshell,然而nc中并没有连接
经过查询(这里应该自己慢慢扫描,原因是管理员对iptables or Firewall进行了配置),靶机之开启了443端口进行交互,所以我们将php-reverse-shell
的port设置为443,bp重新发送,nc也监听443端口,点击shell.php
成功拿到反弹shell
发现python能用,遂将哑shell升级为交互shell,然后获取一波os信息
1 |
|
用lsb_release -a
查看版本号
wget和gcc靶机上均能使用
kali上searchsploit
查找exp
用bp写入靶机文件,gcc编译后执行,无一有效
遂借鉴walkthrough,etc下存在chkrootkit 0.49,chkrootkit是一款防rootkit的shell脚本,可是其自身也存在漏洞,可以被利用于提权
查看该文件后得到提权思路
把我们提权代码保存在/tmp/update
中,chkrootkit一段时间后便会执行它(通常以root权限)
下面是是exp
1 |
|
等待一段时间后,执行sudo su - root
,拿到root权限,get flag
我们查看一下root下的newRule文件
果然防火墙设置只有22、80、8080、443端口能够进出
/etc/sudoers
中添加命令的格式:www-data(用户名) ALL=(ALL)NOPASSWORD:ALL
获取 SickOS 1.2 Flag (CTF Challenge)
Vulnhub SickOs: 1.2 Walkthrough
fb 安全工具 | 利用curl 突破服务器限制,进行安全渗透测试
CTF LIKE就很扯,少打
——鲁迅
1 |
|
Host is up (0.00049s latency).
Not shown: 65531 closed ports
PORT STATE SERVICE VERSION
25/tcp open smtp Postfix smtpd
|_smtp-commands: ubuntu, PIPELINING, SIZE 10240000, VRFY, ETRN, STARTTLS, ENHANCEDSTATUSCODES, 8BITMIME, DSN,
|_ssl-date: TLS randomness does not represent time
80/tcp open http Apache httpd 2.4.7 ((Ubuntu))
|_http-server-header: Apache/2.4.7 (Ubuntu)
|_http-title: GoldenEye Primary Admin Server
55006/tcp open ssl/unknown
|_ssl-date: TLS randomness does not represent time
55007/tcp open pop3 Dovecot pop3d
|_pop3-capabilities: CAPA RESP-CODES TOP AUTH-RESP-CODE UIDL STLS USER SASL(PLAIN) PIPELINING
|_ssl-date: TLS randomness does not represent time
MAC Address: 00:0C:29:3F:27:D6 (VMware)
Device type: general purpose
Running: Linux 3.X|4.X
OS CPE: cpe:/o:linux:linux_kernel:3 cpe:/o:linux:linux_kernel:4
OS details: Linux 3.2 - 4.9
Network Distance: 1 hopTRACEROUTE
HOP RTT ADDRESS
1 0.49 ms bogon (192.168.206.150)
按照提示,让我们访问一下/sev-home/
去登录
bp抓包分析后,发现传出参数是username:password
的base64编码,可以爆破一波
直接尝试nc连接,居然可以连接上
看一下支持的命令
SMTP枚举三把梭:
果然,msf还是最强那把梭,另外两把都没有扫出来东西
手工测试出来root也在范围之内,上面没有显示
下一步怎么走?
枚举用户
单线程py居然跑瘫了机子,SMTP无果
依旧采用nc连接,端口55007
使用CAPA
命令查看server支持的操作,尝试手工测试,msf同步进行登录测试(太慢)
没有得到可用用户名和密码,登录失败,我这里猜测在pop server的某个账户中会隐藏重要信息
CTF LIKE就是这么trick,不真实。翻看js源码,有一句叮嘱,出现用户名和密码,unicode转换到ascii,Boris首字母改小写
账密:boris:InvincibleHack3r
顺利进入
GoldenEye的第二句话有重要信息
Please email a qualified GNO supervisor to receive the online GoldenEye Operators Training to become an Administrator of the GoldenEye system
我们需要发送一封email给主管来称为GoldenEye的管理员,那么下一步需要考虑如何利用SMTP和POP3,先尝试了用这个账密登录POP3,失败!
重新理一下资料
1 |
|
发送邮件动作可以完成,但是接收没有下文,POP3 msf爆破过慢,采用我们拿到的SMTP的用户名和boris
用hydra或者medusa进行爆破
用户名文件user.txt
wordlist采用比较短的fasktrack.txt
hydra使用命令
1 |
|
不到5分钟,爆破成功!
netcat登录pop3,输入账密boris : secret1!
使用list
命令,发现存在3封邮件,使用retr 数字
依次阅读
第三封邮件有点东西
1 |
|
Xenia是个可疑的名称
Attached
就是最终密码?还是附件的意思?
如果是附件的话,我们用python获取一波附件(这里也可以直接用邮件软件查看,配置好pop3和smtp服务)
啥也没找到,思路陷入僵局,求助walkthrough
拿到natalya的账密,root爆破无果
natalya : bird
第二封信件中拿到xenia账密
xenia : RCP90rulez!
同时得到新的路径信息,severnaya-station.com/gnocertdir
,不过需要修改dns文件,对应上服务器的ip
windows改C:\Windows\System32\drivers\etc\hosts
,Linux改/etc/hosts
成功进入
输入账密,登录xenia
看下web指纹
Moodle系统,YUI库,PHP,Apache,Ubuntu
Google一下Moodle,存在的漏洞有XSS、RCE、SSRF、SQL注入等等,之后进一步翻翻searchexploit
发现Message处存在交流信息
用户名是doak,继续尝试爆破
成功爆破,获得新账密
doak : goat
二话不说,登入pop3 server
moodle新账密
dr_doak :4England!
登入moodle,发现一个文件,遂下载下来
又是一波提示
上文告诉我们doak博士抓到了admin的登录明文账密,但是他不能直接告诉我们,现在我们需要下载一张名叫for-007
的图片,既然是CTF-LIKE,那么就需要开启应对misc套路的狗招了
图片分析,先用notepad打开看看,发现没有啥信息;然后属性打开,发现标题存在base64编码
解码,得到xWinter1995x!
,推测是密码
kali中使用exif和binwalk查看(没有可提取物)
现在的可疑用户名:for James
,ForJames
,forjames
,James
,james
,admin
, adm1n
,大小写可能有差异,于是python构造好用户名fuzz,bp爆破
账密为admin : xWinter1995x!
,登录之
后面经过一番查找和exp的直接利用,发现都存在问题,再次学习前辈walkthrough
Site administration -> Server -> System paths
中修改Path to aspell
为python反弹shell代码,当在富文本编辑器中点击拼写检查时就会触发这段代码1 |
|
漏洞具体解释如下
想到的搜索关键词
moodle spell checker can't work
,how to make spell checker work in moodle
,how to use moodle spell checker
,how to pentest with moodle spell checker
,exploit moodle with spell checker
逐一检查之后并没有结果,于是仔细回看反弹shell代码处是否写错或者漏掉重要信息
结合之前做DC-1的经验,于是去侧边栏的Site administration -> Server -> Plugin
查看下是否安装该插件,发现在Overview中没有aspell插件信息,可是也没有提供直接安装的接口或者点击按钮
继续google搜集信息
看一下如何在HTML编辑器中安装spell checker,得知aspell是一款GNU的拼写检测器,可是安装需要在服务器内部用apt-get
进行,所以可以肯定这条路到底了,往回返看看别的路!
下面这条信息点醒了我,我们并不需要真正去安装spell checker,因为刚才的编辑器是富文本类型,可能很多插件已经集成到上面了。这么考虑,下一步就要将moodle中TinyMCE editor等富文本编辑器信息搜集。
把刚才google出来的所有编辑器信息先看一遍,发现了有趣的东西,可谓字字珠玑
moodle已经不支持Google Spell,可是moodle默认又是Google Spell,所以我们的aspell点击不会成功。这里又说明了,只要能够看见aspell的system path,就说明aspell已经安装。下面就只需要按照提示完成spell engine的修改,路径是Administration > Site administration > Plugins > Text editors > TinyMCE HTML editor > Check spelling
保存后,kali上设置好nc监听,找个富文本编辑器点击检查,getshell
继续搜集信息,查看当前用户权限,系统版本
发现能用python,升完交互shell后,kali上searchexploit找提权exp
就采用第一个overlaf,本地gcc编译一波,本地python开启http server下面就想办法将其传到靶机上
继续在靶机上测试发现能使用wget,遂下载overlaf二进制文件,为其修改权限后执行,成功提权
这里有点互相trick的感觉,我把靶机的gcc缺失问题给屏蔽掉了,一般来说需要从靶机wget到exp再本机编译,然后才会遇到没有gcc的问题,再改掉exp内部的编译命令,将gcc改成cc或者clang
下到/root/
看flag
拿到flag,访问/006-final/xvf7-flag/
Penetration Testing an SMTP Server
Talk is cheap, show me writeup
用到的工具和知识
nmap、searchsploit、enum4linux
nmap探查端口
服务
操作系统、脚本等扫描
可见有http、samba等
访问一下网页
dirb扫描
nikto扫描
enum4linux扫描(略多)
1 |
|
进入网页之后一番查找,并无建设性的信息出现,这么来看就是需要凭借之前的扫描信息判断漏洞
复制到文件夹下,编译,查看使用方式
源代码内使用方式
按照要求运行,get root!
复制到文件夹下,编译报错
Talk is cheap, show me writeup
用到的工具和知识
nmap、dirb、nikto、google、searchsploit、shellshock、
nmap探索
开放22/ssh,3128/http-proxy,关闭8080/http-proxy
Google Squid
Squid Cache是HTTP代理服务器软件。Squid用途广泛,可以作为缓存服务器,可以过滤流量帮助网络安全,也可以作为代理服务器链中的一环,向上级代理转发数据或直接连接互联网。Squid程序在Unix一类系统运行。
Squid 是支持 HTTP,HTTPS,FTP 等的 Web 的缓存代理。它通过缓存和重用频繁请求的网页来减少带宽并缩短响应时间。Squid 拥有广泛的访问控制,是一个出色的服务器加速器。它运行在大多数可用的操作系统上,包括 Windows,并根据 GNU GPL 许可。
Squid 由于是开源软件,有网站修改 Squid 的源代码,编译为原生 Windows 版;用户也可在 Windows 里安装 Cygwin,然后在 Cygwin 里编译 Squid。
我用浏览器直接访问靶机web站点
访问不通,那么根据上面搜集的信息,就说明这个站点需要用自己的代理服务器区访问。
于是我在浏览器用SwitchyOmega设置代理,同时使用dirb,nikto设置代理扫描靶机
找到robots.txt文件,发现/wolfcms
,成功进入cms页面,可以看到由用户administrator
发表的两篇博客
进一步侦查,使用dirb爆破/wolfcms
下目录
查看所有扫到的目录,发现/wolfcms/doc
下的update.txt,显示该wolfcms详细版本是0.8.2
在kali中使用searchsploit搜索wolfcms 0.8.2,无果,搜wolfcms 0.8
查看两个poc,后发现后台登录地址为/wolfcms/?/admin/login
下面的思路是sql注入、爆破
先尝试sql注入,手注三次
到这里思维有些停滞,可能有什么信息丢掉了,回头看了看扫描结果,发现nikto中显示存在一些漏洞
如下:
1 |
|
看到shellshock,中文译为破壳漏洞,自然要学习一番~
使用shellshock并不能直接进行登入后台,但是可以直接连接服务器
那我先放放ε=ε=ε=┏(゜ロ゜;)┛
只好上网借鉴walkthrough,什么???也是猜的!admin/admin,那我的思路可能进了兔子洞,上来就把用户名定为administrator,后面就麻烦很多
登上管理员,四处看看后台,发现一个文件上传点,上传一句话成功,修改权限为777
蚁剑连接,进入虚拟终端,查看系统基本信息
查看系统基本信息
四处查看系统及应用配置文件,找到/var/www/wolfcms
下的config.php
,存在密码和账户
查看用户
发现账户root和sickos
那么我们先要获取一个真实的shell,虚拟终端中不支持某些高级操作
老办法,kali用nc监听端口,靶机上用蚁剑放个reverse-shell.php
,设置好ip和port,php -f reverse.php
执行,成功连接!
将fake shell升级到交互shell,python -c "import pty;pty.spawn('/bin/bash');"
执行su
,john@123
并非root密码,试试sickos,成功
直接用ls -l /root
没有权限,之后用sudo ls /root
,发现flag文件
再用sudo cat /root/a0216ea4d51874464078c618298b1367.txt
,直接查看
搞到flag
上面虽然得到了flag,可是有投机成分,没有提权成功,下面是通过学习前人walkthrough得到的提权方法:
先使用id查看该用户所属组,使用sudo -l
查看该用户在sudo下可以执行的命令,命令详解见参考资源[4] [5]
sudo -i
sudo -s
输入密码john@123
sudo su
输入密码john@123
/var/www
下拥有root执行权限的connect.py提权,参考资源[6]可以看到sickos用户的id很有意思
它在sudoers内,所以使用sudo可以执行高级命令,之前这一步还是漏掉了,connect.py的执行权限亦然
这个放到我的另一篇blog中讲解学习
[3]关闭PHP Credits和隐藏的GUID图片Logo彩蛋的显示
[6]write-up sick-os 使用connect.py,很有趣,不过使用了msfvenom
[7]VulnHub ‘SickOS: 1.1’ 破壳讲的不错
]]>Talk is cheap, show me writeup
用到的工具和知识
nmap、dirb、nikto、google、searchsploit、ftp
nmap先行,探测ip和端口
1 |
|
浏览器访问80端口,蹦出一个meme图,robots.txt发现一个/secret/
路径,看过去另一个meme头像也跳了出来
嗯?我既不着急也不抓狂,甚至还有点小兴奋?yea,imma memeable person
因为nmap扫描信息中ftp服务端为vsftpd 3.0.2
,且允许匿名登录,那么就登录一下看看
1 |
|
登陆后查看服务器内容
有一个流量包,下载到kali上
退出ftp,用wireshark分析流量包,同时搜索FTP包
这个数据包是某个用户的操作(12为客户端,06为服务端):
匿名登录–>查看系统类型–>请求服务器主动连接本地端口–>查看目录内容–>切换到二进制模式–>请求服务器主动连接本地端口–>上传secret_stuff.txt文件–>切换到ASCII模式–>再次查看目录内容–>退出登录
进一步寻找,我们过滤ftp-data
协议,找到如下内容
推测:
把rolmao
下载下来,文本形式打开,发现头部有ELF(Executable and Link Format 可执行可连接模式文件),遂放到Kali内执行
1 |
|
于是延续之前的思路,当成路径访问一下
查看密码和用户名,保存下来用于爆破
使用hydra和medusa均可,然而并没有一个成功😂,到这里作者已经给我安排了3个小trick,按照这个作者的骚思路,再来一个也有可能,这个或许就是,名字文件我把删掉的注解复原,再进行爆破,失败。
再回头看看,密码文件是Good_job_:)
,感觉并不是一个密码,反而像一句单纯的鼓励,那岂不是没有密码?那么密码在哪?用户名可能是密码,两个文件名长度不一,密码文件名比较短,有没有可能就是文件名为密码?把上述想法记入Pass.txt
再次爆破。
糟糕,爆破这一块似乎作者做了些限制,一直断连,一次次尝试之后终于
我们立马用ssh登录一下
1 |
|
骚作者还给我设定了登录时间
用刚才的版本信息搜一下系统漏洞,看好前两个
老办法,用nc传输
靶机接收,编译,运行
成功提权!拿到proof.txt
Talk is cheap, show me writeup
用到的工具和知识
nmap、dirb、nikto、google、searchsploit、LFI、BurpSuite、netcat
nmap查找基本信息
80和8080端口开启
访问80端口
8080端口
8080端口暂时没有权限访问
用工具继续收集信息
我们用目录遍历工具dirb、nikto、whatweb
1 |
|
发现whatweb扫描80端口出来一个http://192.168.206.141/pChart2.1.3/index.php
,访问一下试试
发现是个图表生成页面(PHP做的),这应该就是靶机入口了,进一步侦查,可以点击相应按钮阅读代码,发现都是先将PHP包含进来
访问http://192.168.206.141/pChart2.1.3/class/
,出现如下页面
既然已经出现了一个路径,可以想到能访问的不止这一个路径,于是在其基础上继续用dirb、nikto扫描
1 |
|
可以看见nikto扫描结果中出现了如/pChart2.1.3/?=PHPB8B5F2A0-3C92-11d3-A3A9-4C7B08C10000
这样的链接,我们访问试试,有些是图片,还有一个是所谓的phpinfo
这个PHP Credit只有模块名和作者名,其他什么都没有。这里我想是不是phpinfo这一块有盲区,于是Google一番,没有什么实际效果。(第一个兔子洞)
思路卡壳,遂上网借鉴walkthrough
按照这个思路,我继续Google
这里也可以直接在kali上用searchsploit,不过可能性会比Google小,所以要抱有一种乐观的冷静
测试这两个poc,可以运行,但是我又陷入了不知道该做什么的境地,原因还是对于这个环境不了解,不知道那些信息对于渗透比较重要,于是根据上面的想法提炼关键词:apache 敏感信息、apache 2.2.21 敏感信息、PHP 5.3.8敏感信息、 Apache默认路径
找到如下两个有用信息:
还是一番执行过程中看不到希望的测试(因为效率低,所以要编写脚本or搜集更多有效信息),终于发现一个有效敏感配置信息
篇幅不长,仔细阅读非注释信息后,发现8080端口不能访问是因为设置了只允许浏览器为Mozilla4通过
好,到这一步我想到修改UA,那就使用BP,将Mozilla 5.0修改为4.0后,8080页面即可见
可是我后续要一直访问这个端口,每次手动改不现实,那么就用Match and Replace
实现修改通过bp的每个数据包
ok,点击index,成功进入下一步,是个PHPTAX,有了经验,继续用之前总结的方法论,上Google & searchsploit
找到相应漏洞版本,exploit
复制粘贴保存txt内的PHP exp,按照参数执行
报错,说没有curl_init()
,Google如何开启
修改php.ini
内;extension=curl
去掉前面的;
注释,再次运行如上图,查找后并没有curl的动态链接库(Linux下为so,Windows为dll)
大概2个小时的调试安装(因为我用的2018版kali,😭),终于见到下面这张图
unsuccessful!那么我换个exp,用/usr/share/exploitdb/exploits/php/webapps/21665.txt
持续失败,休息了一会,决定阅读一下刚才的exp源码,把url复制粘贴到浏览器,访问成功
尝试下一步的时候,却说不存在rce.php,传shell不成,难不成真要使用msf?不存在的,/phptax/
继续目录爆破
挨个路径访问,发现phptax/data/
路径中我们的php shell的确已经写入,但是执行不了,同时发现phptax/data/pdf
路径也有料
再次借鉴walkthrough!
发现有些前辈可以执行命令,有些却并不能成功,同时他们也发现靶机上没有bash,没有python,有sh,可是用url直接访问依然不能工作,测试telnet也失败。(当然msf还是一波带走)
他们成功的方法:
$
前添加\
转义,比如`echo @eval(\$_POST[‘psw’]);我参考第二种方法
可以直接查询信息,但也不能直接连接(nc秒断)
那么试试nc传送(也可以用ftp)php-reverse-shell.php,我们在/usr/share/webshell/php/
中找,改好ip和端口
1 |
|
接收成功!我们在kali上监听,浏览器中访问shell.php
提权就很简单了,直接以OS版本FreeBSD为关键词搜索exp
我们下到/tmp
目录,直接用nc将exp传入靶机,gcc编译运行即提权
在/root
下找到congrats.txt
Talk is cheap, show me writeup
用到的工具与知识
nmap、hydra、cewl、whatweb、metasploit、脏牛提权
nmap刺探一下信息
可以看到开启了22/ssh,80/http,1898/http,三个端口,看到ssh可以想到ssh爆破。
先往下,我们先进一步搜集信息,不贸然出动
用浏览器访问一下网站相应端口
一个船长的人头?我喜欢,我们再看看别的端口
嗯,一个不错的Drupal CMS,仔细观察之后发现两个用户,再看一眼文章内容
我把文章页面的内容用cewl
抓下来做成字典,再加上之前的用户名我们用来爆破ssh
小插曲:
有够幸运(因为这靶机一般不可能是用爆破来解),我们爆破出来了一个ssh账户密码,登一下试试,直接拿到了一个低权限的账户。
经过一番长时间的试错,我们从众多exp中找到了能用的DirtyCow(脏牛提权),原理是直接将密码算法逆向解密,所以跑起来很快。上传文件(我用的MobaXterm)之后,按照exp内的提示在靶机上编译运行
成功提权,拿到flag
回归正常流程:
从CMS进一步获取信息,服务器等中间件的信息可以使用whatweb
路径、敏感文件、指纹什么的,我会用Nikto、dirburster、dirb
由上面找到的信息,进一步查看robots.txt
发现能够看CHANGELOG.txt,这个文件一般会包含详细版本号,以及大量修改信息
果然,可以看到详细版本号是Drupal 7.54
看到CMS我就忍不住想测试一下逻辑漏洞、XSS和SQL注入。结果发现创建不了用户,密码找回和SQL注入也相继失败,那么我只好从exploit-db找找有没有相应的drupal漏洞了。
嗯,用rb的exp得到一个fake shell,路径都无法变更。。。
又是一番试错,我们打开了msf,search drupal 7.54
,自然选择时间靠后的exp
1 |
|
显示参数有什么需要填写,填写相应参数
1 |
|
成功拿到meterpreter,进入目标机的shell,我看看基本信息
1 |
|
OK!到这一步我就直接用之前的脏牛提权解决问题
1 |
|
发现一张帅图,你好,船长!(虽然是寨主)
Talk is cheap, show me writeup
用到的工具和知识
nmap、whatweb、searchsploit、netcat、SUID提权
我们先开启靶机和kali,两者均为NAT模式
我用mobaxterm连上kali(192.168.206.128),用nmap扫描局域网找到靶机ip(192.168.206.137)
扫一下靶机端口,发现开启了ssh、http、rpc
我们再查看一下所有信息
可以看到相应的ssh版本,google了一下发现此版本不能爆破
验证:
爆破之后报错
[ERROR] target ssh://192.168.206.137:22/ does not support password authentication.
网上解答,并不支持password认证可能是设定要用键盘键入提示框那种认证
ssh放掉,那我们继续往下,看到扫描记录有http服务和相应的目录,我们顺势firefox访问一波主页
上网搜了一下 Drupal,是个广泛应用的开源cms,当然也有相应的CVE
尝试创建账号,发现还需要管理员认可才能创建账号,GG,还是按照正常程序走吧。
用whatweb
探查一下所用的技术,发现
PHP:5.4.45-0+deb7u14
Apache:2.2.22
OS:debian
Drupal version:7
我们得到了一些基本信息,可是比较重要的cms详细版本号没搞到,而且试图查看CHANGELOG.txt也不可用(被删或改名)
既然想高效一点,我们还是先找找exp,这里可以上exp-db去找,当然我也可以在kali里用searchsploit drupal 7
找找kali自带离线库内所有version 7的exp
选择红框内脚本,添加一个admin用户
可以看到我们的脚本成功执行了,我们直接用刚才创建的账号登进去,一番搜查发现有个flag3页面,
这句话似乎给我们打了个哑谜,能发现他强调了FIND、PERM和exec,继续找找发现并没有什么可以利用的,于是google了一下思路,ε=ε=ε=┏(゜ロ゜;)┛
其实可以装个shell插件的,对于web后端可能会有这样的服务,学习了,我们继续往下进行
我们找到后台的模块安装处,直接点击安装模块
有两种安装模式,直接用链接模式,我们在原来的shell module页面底部找到插件,提取链接,粘贴到相应位置,安装
安装完成,我们看看模块,发现任何用户都可以使用这个shell模块,可是在模块处并不能直接打开shell,找了找shell的位置,在dashboard发现了shell链接,我们点开
cool!看看OS版本和用户信息,find查找flag文件,发现了一个flag1.txt
1
2
3
Linux DC-1 3.2.0-6-486 #1 Debian 3.2.102-1 i686 GNU/Linux
uid=33(www-data) gid=33(www-data) groups=33(www-data)
Debian GNU/Linux 7 \n \l
我这里先采用nc拿个反弹shell,再用python pty升级为交互shell
1 |
|
找到flag4.txt
,我们能用相同的方式找到root的flag吗?可能吧,不过没那么简单,又或许很简单
从寻找flag1 3 4 过程中我们能够体会到,作者一直在提find,而且我们用find查找的时候也不那么顺心,似乎权限有限制。
好那么就顺着作者引导的思路,再次google find 提权
除去第一个结果(考试的时候泄题机ji率ben较wei小ling),别的搜索结果比较让人满意,看来思路还没跑偏,确实有这么个东西,赶紧拿过来学学
我试了试vim提权,结果到文件里出不来,反弹shell都亲手干掉了
看了下root权限的可执行文件,vim也不在其中,算了,直接find提权
条件是:
-exec
并不会执行-exec
语句会被执行多次(这条某些情况下可以忽略)这里有两种方式:
/var/www
下查找一个单一的文件测试成功,读取到最后的flag,然鹅这里只有用/bin/sh
才能提权而/bin/bash
无法提权,查了点资料,不过也不在点上,暂且留坑了
- /bin/bash(Bourne-again shell)是sh的扩展版,Linux默认shell就是bash,与 sh(Bourne shell) 完全向后兼容,并且在Bourne shell 的基础上增加、增强了很多特性。Bash放在/bin/bash中,它有许多特色,可以提供如命令补全、命令编辑和命令历史表等功能,它还包含了很多 C shell 和 Korn shell 中的优点,有灵活和强大的编程接口,同时又有很友好的用户界面。
- 在一般的linux系统当中(如redhat),使用sh调用执行脚本相当于打开了bash的POSIX标准模式,也就是说 /bin/sh 相当于 /bin/bash –posix
- GNU/Linux 操作系统中的 /bin/sh 本是 bash (Bourne-Again Shell) 的符号链接,但鉴于 bash 过于复杂,有人把 ash 从 NetBSD 移植到 Linux 并更名为 dash (Debian Almquist Shell),并建议将 /bin/sh 指向它,以获得更快的脚本执行速度。Dash Shell 比 Bash Shell 小的多,符合POSIX标准(某条语句错误则不往下执行)。
咦!(⊙﹏⊙)做完了发现,收集了flag134,那2呢?
回头看看flag1的提示
1 |
|
他是在说网站配置文件,我们找到/val/www/sites/default/settings.php
教我们暴力并不是王道,反推可以暴力啰
好!用给的账户密码登入mysql
1 |
|
拿到各个账户密码,用hashcat,这里就打住了,小辣机没有强大的GPU,不硬跑了
本次织梦的版本是V56_UTF8
我们先创建一个账号test,开始在内容中心写文章
然后我们在所有输入框,插入<img src=1 onerror=alert(0) />
,输入验证码后发表
预览文章发现并没有弹窗。
可是我发现在预览文章页面有评论框,那么我们试试评论
发现可以成功
csrf+xss攻击链:在文章区or评论区留下存储型xss,当管理员审核的时候,该xss将在管理员访问的HTML页面新建一个<script>
标签,将其src指向我们服务器上的xss.js文件,也就是把xss.js包含进来,而xss.js的效果是在/data
目录中建立一个test.php
文件(小马)。
于是我们开始配置服务器上的xss.js文件,即将xss.js放在phpstudy的WWW文件夹下
1 |
|
我们在评论处插入
1 |
|
登上管理员账号,审核普通文章,预览文章
因为代码中是将文件写入data文件夹,so查看一下data(模块->文件管理器->data)
上菜刀,拿shell
几年前在学习RASP的时候需要下载v8引擎,可是直接在外网下又太慢,组内负责这块的小伙伴当时没有好资源、眼光也浅,于是我现在翻翻老底,把以前的问题解决一下,给我的kali和centos7(without GUI)配置ssr
先决条件:我的windows物理机上有已经配置好的ssr和v2ray,kali和centos使用NAT连接,su权限
telnet ip port
/etc/profile.d/
下新增配置脚本文件写入配置export ALL_PROXY=socks5://ip:port
执行初始化
以上是浏览器的socks5代理,但是如果到了命令行环境下,我们依然想用代理连接外网呢?
这里用的kali的termimal演示
wget
获取google失败1 |
|
1 |
|
1 |
|
在v2ray中直接开启允许来自局域网连接
,然后按照上述配置10808端口后,你会发现还是无法连接,用wget测试terminal报如下错误
查看v2ray的日志
问题的原因是,v2ray有SOCKS5代理端口和HTTP代理端口,如下图(端口被我改过)
注意v2ray需要填写正确端口
说到全局配置,当然直接就在kali的网络设置中配置代理
网络设置->Network Proxy,写入ssr所在主机地址:端口
OK,可以上网了
git status
1 |
|
1 |
|
HEAD是当前分支最近一次提交的引用
1 |
|
不过,HEAD指针默认指向当前分支指针(branch pointer),但可能引用与当前分支名称不相关的的commit时,我们称这种为游离HEAD(detached HEAD)
,在这种情况下使用git commit
产生的是快照
图
图
文字
在使用git过程中,我们可能会误删文件,于是我们想回到最近一次或是特定某次commit,重新写文件。但是当提交次数过多我们就记不住到底是哪一次修改了什么内容,所以我们需要git来查看历史
git log
1 |
|
git reset 某一版本
我们使用git reset HEAD^
回到当前上一个版本
1 |
|
git reset HEAD^^
回到当前上两个版本
1 |
|
git reset HEAD~100
当前上100个版本
1 |
|
这里有一个问题:
我们查看历史发现之前的版本已经消失,但是如果我们还想回到之前删除的版本怎么做?
git log
产生的哈希值,这样我们就可以回到未来!1 |
|
可是问题又来了:
我们如果关掉了之前操作的shell窗口怎么办?
git reflog
命令可以救你一命。它记录了你的每一次命令中的commit id1 |
|
这次我们来学习一下git里的分支,它Todo,建议先用learngitbranching实操学习,在脑中建立一个实际的印象,再看blog
1 |
|
git checkout -b hexo
完成这里我们增加文件y.txt
,再在文件x.txt
后增添几个字符,在hexo分支下加入仓库并提交
可看到
1 |
|
我们切换回master
1 |
|
这里注意一下是谁合并到谁的逻辑:
master把hexo合并过来 == hexo变成现在master的一个<同一结点>or<父节点>
将hexo分支的工作成果合并到master分支上,也就是git中的Fast-forward
模式,合并速度非常快
因为这里master之后没有commit,所以直接是master指针移动到hexo指针所指位置,指向同一结点
1 |
|
hexo变成master的一个父节点
完成合并之后我们就可以删除hexo分支了
1 |
|
1 |
|
我之前会用一些git,教给小组里的同学使用的也是简单的turtoise,完全不用自己处理上传逻辑,所以现在开一个系列,系统地学习一下
1 |
|
注意点:
git只能追踪文本文件的改动,比如添加/删除某些内容,不能准确追踪二进制文件的改动,只知道大小的改变
使用Windows的童鞋要特别注意:
千万不要使用Windows自带的记事本编辑任何文本文件。原因是Microsoft开发记事本的团队使用了一个非常弱智的行为来保存UTF-8编码的文件,他们自作聪明地在每个文件开头添加了0xefbbbf(十六进制)的字符,你会遇到很多不可思议的问题,比如,网页第一行可能会显示一个“?”,明明正确的程序一编译就报语法错误,等等,都是由记事本的弱智行为带来的。建议你下载Notepad++代替记事本,不但功能强大,而且免费!记得把Notepad++的默认编码设置为UTF-8 without BOM即可:
然后将编写的文件放入文件夹(复制,新建等)
再将文件添加到git仓库
1 |
|
最后将文件提交到git仓库
1 |
|
git status
显示版本库当前状态
1 |
|
git diff
查看文件是否被修改,修改了哪些部分
1 |
|
最近在docker上搭建了部分漏洞实战平台,感觉docker这玩意很好使,所以学习一波
1 |
|
docker-compose up
1 |
|
1 |
|
REPOSITORY
TAG
IMAGE ID
CREATED
SIZE
以上均存储在/var/lib/docker下
1 |
|
NAME
DESCRIPTION
STARS
OFFICIAL
AUTOMATED:自动构建,表示该镜像由docker hub自动构建流程构建
1 |
|
例如,下载centos镜像
1 |
|
1 |
|
删除所有镜像
1 |
|
1 |
|
查看所有容器
1 |
|
查看最后一次运行的容器
1 |
|
查看停止的容器
1 |
|
1 |
|
(1)交互式方式创建容器
1 |
|
这时我们用ps命令看可以发现启动的容器,状态为启动
退出当前容器
1 |
|
(2)守护式方式创建容器
1 |
|
登录守护式容器的方式
1 |
|
停止容器
1 |
|
启动容器
1 |
|
文件拷贝
将文件拷贝到容器中
1 |
|
文件从容器拷贝除来
1 |
|
创建容器时,将宿主机的目录与容器内的目录进行映射,这样我们就可以通过修改宿主机某个目录的文件从而去影响容器
创建容器 添加-v
参数 后面为 宿主机目录:容器目录
例如:
1 |
|
如果你共享的是多级目录,可能会出现权限不足的提示
因为centos7中的安全模块selinux把权限禁掉了,我们需要添加参数--priviledged=true
来解决挂载的目录没有权限问题
可用以下命令查看容器运行各种参数
1 |
|
也可以直接执行下面命令输出IP地址
1 |
|
1 |
|
该库是mysql数据库中记录所有表的信息,为我们提供了各种状态、权限和配置信息等等。
Mysql中的INFORMATION_SCHEMA数据库包含了一些表和视图,提供了访问数据库元数据的方式。
元数据(数据词典、系统目录)是关于数据的数据,如:数据库名或表名,列的数据类型,访问权限等。
说明:
1 |
|
插入
1 |
|
删除
1 |
|
修改
1 |
|
查询字符串
1 |
|
e.g.
查询以‘DB_’开头,且倒数第三个字符为i的课程的详细情况。
1 |
|
表的连接
1 |
|
建立索引
1 |
|
给表取别名(用于自身连接等)
1 |
|
聚集函数
1 |
|
GROUP BY 子句
将查询结构按一或多列的值分组,值相等为一组
1 |
|
使用变量
1 |
|
用户变量
不用提前声明,直接使用’@变量名‘,如上面“使用变量”代码块
特点:变量和数据库连接有关,在连接中声明的变量,在存储过程中创建了用户变量后一直到数据库断开,变量才消失。该变量不能跨连接
select @name:=team from organize
如果返回多条的@name只保存最后一条记录
需求:
在建立视图较为困难的情况下,选择建立一张新表
新表需要某一个表的一个字段所有情况作为字段,同时当别的表进行CUD时做出相应的变动,某个人的某种类型题目分数相加。
GRANT
1 |
|
e.g.
1 |
|
REVOKE
1 |
|
e.g.
1 |
|
创建数据库模式的权限
CREATE USER <username>
[WITH][DBA|RESOURCE|CONNECT]
权限 | CREATE USER | CREATE SCHEMA | CREATE TABLE | 登陆数据库,执行查询操作和操纵 |
---|---|---|---|---|
DBA | :v: | :v: | :v: | :v: |
RESOURCE | :x: | :x: | :v: | :v: |
CONNECT | :x: | :x: | :x: | :v:但必须有相应权限 |
角色
1 |
|
1 |
|
(如果不使用on直接添加在where处,就是全表生成笛卡儿积,再做处理,这样产生了大量的临时表,性能极低,比较好的方法是比较好的方法是==使用ON关键字先处理好相应的数据源==,再使用WHERE)
1 |
|
1 |
|
(查询到第一个就结束)
(指向内存中结果集的指针,对内存中的结果集进行操作)
1 |
|
运用
使用FETCH获取记录信息
游标嵌套
查看游标信息
1 |
|
利用SQL Server图形工具进行创建
利用CREATE INDEX 命令创建索引
1 |
|
利用ALTER INDEX命令修改索引
1 |
|
索引碎片检测
索引重组
1 |
|
1 |
|
思路:通过简单地闭合字符串来构造sql语句。
常见闭合情况:单引号、双引号、括号(以及这几种的组合),还有可能直接采用数字(不用闭合)
结合information_schema使用union查询自己想要的数据
注释方式#, –%20, –, –+
没有回显的注入
1 |
|
1 |
|
1 |
|
基于报错的盲注主要就是三块:
count(*)
group by
后连接函数concat
内部floor(rand(0) * 2)
,这里的形式不定,只要满足用其来分组就行group by
后连接函数concat
,你想要通过报错查询的信息,比如:database()
select count(*) from YOUR_SCHEMA.YOUR_TABLE group by concat(@@version, floor(rand(0)*2);
regexp(暂用于盲注)
1 |
|
1 |
|
待分配
1 |
|
析构函数:特殊的类成员函数,没有返回类型、参数,不能随意调用,也没有重载,只有在类对象的生命周期结束时,由系统自动调用,释放内存空间。
虚函数:c++多态的一种表现,使用虚函数,,我们能灵活进行动态绑定,花费一定开销
析构函数也可能时虚函数吗?
1 |
|
'\091'
'\\'
'\0'
'\''
错误的转义字符为?'\091'
% '' ""
,也可以是三个8进制数(0~7) \023
,也可以时两个16进制数(0~f) \af
ClassA
定义并实现虚函数int func(void)
,ClassB
中也实现该函数,那么上述变量a->func()
将调用哪个类里面的函数?如果int func(void)
不是虚函数,情况又如何?why?fclose
一个打开过一次的FILE *fp
指针会有什么结果?main()
引起的?如果不是,请举例1 |
|
virtual
和inline
含义分别是什么?virtual
(强制)主要用于声明虚函数,抽象类、纯虚函数、多态inline
声明内联函数const
关键字有哪些作用?const
const
类型,使得其返回值不为”左值”virtual
函数,如果子类覆盖它的函数不加virtual
,也能实现多态?virtual
修饰符会被隐形继承的,virtual
可加可不加。子类空间里有父类所有变量(除了static)。inline
除外),子类覆盖它的函数不加virtual
也能实现多态1 |
|
1 |
|
1 |
|
这里面的知识对不对还有待考证
1 |
|
1. 多态:重写父类同名函数,让程序根据实际情况运行不同函数2. 纯虚函数:主要用于定义抽象类3. 提示可能在子类中被重写,还有就是动态绑定
语法
高级特性
场景
效率
1 |
|
protection行为 | 能否定义函数 | |
---|---|---|
c | 无 | 否,但可以有函数指针 |
c++ | 有,默认private | 可以 |
int id[sizeof(unsigned long)];
对吗?why?sizeof
是编译时运算符,编译时就确定了,可以看成和机器相关的常量new in c++ is a ()
* 虚拟函数表时在编译期就建立的,各个虚拟函数这是被组织成了一个虚拟函数的入口地址的数组。而对象的隐藏成员虚拟函数表指针是在运行期,也就是构造函数被调用时进行初始化的,这是实现多态的关键。
* 封装:将客观事物抽象成类,每个类对自身的数据和方法实行protection(private, protected, public)* 继承:(1、2为类继承,3为对象组合=>接口继承以及纯虚函数) * 实现继承:使用基类的属性和方法而无需额外编码能力 * 可视继承:子窗体使用父窗体的外观和实现代码 * 接口继承:仅使用属性和方法,实现之后到子类实现* 多态:是将父对象设置成为一or多个与他子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说:允许将子类类型的指针赋值给父类类型的指针
* 做,这是相对与宏的优势
* 静态存储区域分配,编译时已经分配好,程序整个运行期间,如全局变量* 栈分配。执行函数时,函数内局部变量的存储单元都可以在栈上创建,自动释放。分配运算内置于处理器指令集中,效率很高但容量有限* 堆分配。动态内存分配,malloc&new申请任意多少内存,需及时free&delete
* c用宏定义,c++用inline
* 生命周期不同:全局变量随主程序创建&销毁;局部变量在局部函数或循环体内部,退出即消失;* 使用方式不同:全局变量声明后各个部分都可使用,局部变量只能在局部使用;* 实现:全局变量在全局数据区,局部变量在栈区* 操作系统通过内存分配位置知道是何变量。
- 本文件
* malloc/free是c/c++标准库函数,new/delete是c++关键字(or运算符)* 对于非内部数据类型的对象,需要执行构造析构函数,而malloc/free不是运算符,不在编译器的控制范围内,所以有new来完成动态内存分配,delete来清理何释放内存
* 不是,两个不同类型指针之间可以强制转换(用reinterpret_cast)* 类型安全:不同数据类型的数据不能随意地转换来操作。
* 定义一个指针p,打印sizeof(p),如果结果是4(32),结果为2(16)* 不大行的法二1
2
3
4
5
6
int a = ~0;
if(a > 65536) {
cout << "32 bit" << endl;
} else {
cout << "16 bit" << endl;
}
漏洞难度:低
漏洞奖金:未知
漏洞类型:敏感信息泄露
嘿!大家好,最近我看到一个snapchat源码泄露的新闻,黑客把其网站源代码下载下来并上传到了GitHub上。在前些年,
什么是Git?这个我相信大家应该都懂我就不翻了。ε=ε=ε=┏(゜ロ゜;)┛(逃~
Git is a version control system (VCS) for tracking changes in computer files and coordinating work on those files among multiple people. It is primarily used for source code management in software development but it can be used to keep track of changes in any set of files.It allows source code versions to be managed in a logical manner and tracks changes through different ‘forks’ and ‘branches’.
如果一个应用已经错误配置了git目录,使它暴露在外,那么这个文件夹就会像下面这样
为了从这个仓库中递归下载每个文件,wget必然是最佳工具,wget -r https://example.com/.git
。现在一旦你可以下载整个.git
文件夹,你只需要懂一点点git命令行就可以把git对象都搞下来。
这些网站可以参考:
https://blog.netspi.com/dumping-git-data-from-misconfigured-web-servers/
如果你不熟悉git和git命令,那么在进入本节之前,建议读读上面的链接。现在,一起来看看我是怎么在包括印度最大的电信行业在内的多家公司中做到这一点的。
子域名和主域名一样重要,这也就是为啥前期的信息搜集最重要的一部分之一是子域名枚举。并不总是在主域名下发生git错误配置,它也会在子域名下出现,所以为了找到所有意外公开git仓库的域名,我们要把域名爆破和.git
下载组合起来。Sublist3r是基于各种不同资源的域名爆破工具,它会将子域名以列表的形式输出,当然github上还有更多好的工具等你发掘。同样github上还有一个碉堡了的开源项目–Git-dumper,它实现了我们刚才说的两个需求。我把这两个项目的代码合了起来,然后做了点小改动(都放在git-domain.py里),这些改动有:
git-domain.py
需要一个文件作为输入,文件中是你想爆破的主域名,每个域名占一行.git
目录以及是否公开这就是我的所作所为,哈哈,你要做的是准备一个包含各种大、中、小型企业(有公开/私有赏金漏洞项目或src)的域名,然后扔到git-domain.py
里~~
然后我就得到了一大堆git配置错误目录,其中包括印度最大电信服务提供商的,有些还有主站的源代码。
站长或者研发必须确保.git
目录没有被设置为外部可见路径索引,并且使用服务器权限也不允许获取这些目录、子目录及其下所有文件。还有,.gitignore
文件不应该被用于确认敏感文件是否被忽略或上传。大道至简,最佳修复方式就是拒绝.git
文件夹的访问
1 |
|
这种问题我可以用lijiejie
的githack
跑一下,可是现在这种问题还多吗?这篇是18年10月的,这两天我再试试,扫扫edusrc
作者的思路也还容易理解和想到,把现有的工具合并、改造,关键还是要有对于特定场景的前瞻性思路才行
设置持久HTTP连接
将HTTP报文中设置Connection:Keep-Alive
1 |
|
设置空连接
1 |
|
设置多线程
1 |
|
设置预测输出
1 |
|
设置指定测试参数
1 |
|
设置URI注入位置
当注入点位于URI本身内部时,会出现一些特殊情况。除非手动指向uri路径,否则sqlmap不会对uri路径执行自动测试,必须在命令行中添加星号(*)来指定注入点。
例如:当使用Apache web服务器的mod_rewrite模块或其他类似技术时,这就显得特别有用了
1 |
|
设置任意位置注入
与URI注入点类似,星号(*) (注意:这里也支持Havij样式%INJECT%)也可以用来指向GET、POST或HTTP头中的任意注入点。注入点可以通过在带有选项-u的GET参数值、带有选项-data的POST参数值、带有选项-H的HTTP头值、带有-H、–user-agent、–referer、–cookie的HTTP头值中指定,或者在带有选项-r的文件中加载的HTTP请求通用位置指定
反正应该是很多位置都能加了,多试试。
1 |
|
直连数据库
1 |
|
url探测
sqlmap直接对单一url探测,采用-u或者–url
1 |
|
这里我们将bp的project option下loggin勾选上requests立即弹出框,我们自己设置保存地址
google hack批量扫注入
1 |
|
设置HTTP方法
1 |
|
设置POST提交参数
1 |
|
设置参数分割符
某些情况下,sqlmap需要覆盖默认参数分割符(e.g. &在GET和POST数据),才能正确分割和单独处理每个参数
1 |
|
设置cookie头
1 |
|
使用场景
使用过程:
设置User-Agent
1 |
|
设置Host头
可以手动设置主机头,将对HTTP主机进行SQL注入检测,如果–level值设置为5,将对HTTP著机构进行全部探测
设置Referer头
没有显式设置,HTTP请求不会发送HTTP引用头,注意若–level为3或以上,将对HTTP引用头进行sql测试
设置额外HTTP头
通过设置–header,提供额外HTTP头。每个头必须用换行符分割,从配置ini文件中提供他们比较容易。可以查看sqlmap.conf
1 |
|
设置HTTP协议认证
1 |
|
设置HTTP代理
1 |
|
设置Tor隐藏网络
1 |
|
设置延迟
1 |
|
设置超时
1 |
|
设置重置次数
1 |
|
设置随机化参数
1 |
|
设置日志过滤目标
可以指定有效的python正则表达式,用于过滤所需日志
1 |
|
设置忽略401
1 |
|
设置HTTP协议私钥
1 |
|
设置安全模式
避免在多次请求失败后销毁会话,有时执行了一定量失败请求后web应用or检查技术会销毁会话,这可能发生在sqlmap检测阶段or利用盲注阶段
1 |
|
将访问预定义请求数量请求,而部队某个安全url执行任何注入
设置忽略URL编码
1 |
|
某些情况下服务器不遵循RFC标准,需要医院是非编码形式发送
设置额外HTTP头
FIXIT
]]>备案信息
cms指纹识别
web敏感目录探测工具
端口信息
netstat
masscan
和nmap
(单独挑出来学语法)敏感信息
1 |
|
HTTP响应
GitHub
1 |
|
真实ip<可扩展>
判断是否存在cdn(内容分发网络)
1 |
|
如果IP地址不同则存在cdn
绕过cdn
1 |
|
利用IP地址对web地址访问,能访问则为真
语法和实战
命令行安装
easyinstall 安装shodan
初始化shodan
1 |
|
启动并查找具体服务
1 |
|
获取指定IP地址信息
1 |
|
获取自己账号信息&自身ip(鸡肋?应该有不同应用场景)
1 |
|
检查是否有蜜罐
1 |
|
python-shodan
1 |
|
1 |
|
1 |
|
原文链接:毫不费力地挖到XSSI/JSONP漏洞
漏洞难度:中
漏洞奖金:$800
漏洞类型:XSS
大家好哇!我最近在私有项目中上报了一个价值$800的XSSI(XSS包含)漏洞,于是我决定分享一下我在挖洞中遵循的方法论
如果你还不太懂XSSI和JSONP,那么好好读读下面的文章:
XSSI:https://www.scip.ch/en/?labs.20160414
JSONP:https://www.sjoerdlangkemper.nl/2019/01/02/jsonp
我找到了一个JS文件,它里面包含我刚才注册填写的所有信息,包括社保号,病历,银行卡信息,名字,电话号,住址等等
我马上扫了一眼这个JS的GET请求,再次确认它headers里没有CORS triggering(同源策略触发设置),就像:Authorization,X-API-KEY,X-CSRF-TOKEN,X-whatever
到了这个阶段,如果它确实设定了同源策略,那么攻击就会失败,除非我也找到它的一个同源漏洞
在这种情况下,并不需要特殊的headers,所以我能在web页面上用一个标签把JS文件包含进来,同时把它发送到任意一个泄露大量身份认证信息的服务器
POC如下:
1 |
|
你可以用一样的办法去找JSONP回调,比如添加参数 callback=some_function, jsonp=...
等等,可以在返回敏感信息的所有路径下做这样的测试
有时候你需要多个参数去触发一个JSONP response。比如
1 |
|
如果response中有Content-Type: application/json
但是返回体中有JSONP/javascript
,而且没有X-Content-Type-Options: nosniff
,我们依然可以利用漏洞
对于JSONP,即使在同一个网站,不同的回调参数可能作用在不同的地方。比如:
1 |
|