[DDCTF 2019]homebrew event loop
打开环境,我们发现有四个页面
第一个页面是个python的flask框架
第二个页面我们能进去花费一个积分买钻石
第三个页面是重置积分
我们重点来看第一个页面
1 | from flask import Flask, session, request, Response |
进行代码审计
看到有两个命名与flag相关的函数
我们先看get_flag_handler(),要想flag就要满足session[‘num_items’] >= 5
在这里面提到了trigger_event(),来看一下
1 | def trigger_event(event): |
这个函数失望session里写日志,会记录下各个函数的调用,那么自然会吧trigger_event(“func:show_flag;”+FLAG())存在放在session[‘log’]中,那么flag就会在session里
现在要想想怎么满足session[‘num_items’]>=5
1 | def buy_handler(args): |
buy_handler()回显加上num_items,然后在执行consume_point_function()函数,在consume_point_function()函数中,如果发现points不够会回滚,就是把num_items再减掉
但我们只有3个point,买不了5个num_items怎么办
那我们就要在num_items被减掉之前执行get_flag_handler()不就行了
我们来看
1 | def execute_event_loop(): |
可以看到里面有一个可控的eval函数,利用这个函数可以导致命令执行
若让eval()去执行trigger_event(),并且在后面跟着buy和get_flag,那么buy_handler()和get_flag_handler()便先后进入队列,那么这时consume_point_function()就会在get_flag_handler()之后
payload
1 | ?action:trigger_event%23;action:buy;5%23action:get_flag; |
得到cookie
我们进行session解密
得到flag