赛博杯2019 Write Up
帮朋友打打CTF,挺好的,长长见识
Pwn
0x1 hardpwn
导入IDA后,发现需要覆盖运行参数(即argv),因为栈溢出很长且可以覆盖到该参数,所以可以考虑直接覆盖
1 | from pwn import * |
运行后拿到flag: CyCTF{W3lc0me_t0_CyCTF_PWN}
0x2 stackpwn
导入IDA后,发现没有puts、write等,只有read且有溢出,那么这道题就是典型的考察ret2_dl_resolve
利用roputils简化攻击
1 | from roputils import * |
0x3 floatpwn
这题考察了确定浮点寄存器通过movss写入内存时的数值
方法:只能人工二分法一次一次去尝试,然后发现小数点后45位之后可以忽略不计,真正开始有意义的数值在小数点后45位开始。然后求出对应的n使得写回内存时是我想要的数值,从而构造ROP链。但是想构造ROP链之前需要实现无限写,所以输入size时,可以考虑输入负数,实现无符号整数溢出,从而无限写。因为控制写入数据位置的i变量位于栈空间底部,所以要使得写到i里的数据为10到12即可,因为可以考虑直接略过ebp,直接修改rip。
1 | from pwn import * |
0x4 codepwn
通过逆向可以发现程序将flag存入了内存中,并且我们可以选择flag对应的下标进行对比,可是4字节的shellcode有着限制,并且v5是call shellcode之后的返回值,那么就必须在shellcode中对rax进行赋值操作,可以观察到r9寄存器的大小是跟printf出来的字节数相关,那么就可以通过push r9,pop rax,ret,三个操作来对rax赋值,进而根据程序最后的判断来确认我们猜测的flag对应下标的那个字母是否正确,接下来就是爆破就完事了
1 | from pwn import * |
0x5babyheap
由于有一个check过不去,导致我没办法fastbin attack,总的来说是我太菜了。
0x6 babytcach
checksec 可以看到程序没有开PIE,同时bss中存放了_IO_2_1_stdout_的地址,并且libc2.27有double free,所以思路就很明确了.有了double free就可以malloc 2 everywhere,所以这样一的难点在于如何leak libc,通过double free,可以让fd指向_IO_2_1_stdout_,从而malloc 2 IO_2_1_stdout,从而修改write_base来leak libc,之后再double free去修改free_hook为system,去free一个/bin/sh就可以了
1 | from pwn import * |
Misc
0x1 sign in
扫码即可得到flag
0x2 No_Word
snow加密,将文件放入010editor看他的十六进制形式。
0D0A是换行,剩下的将20转0,将09转1,得到的二进制数据,转字符串即可得到flag。
0x3 基础社工
题目介绍:大家都用着我们的数字杭电(i.hdu.edu.cn)但是对于其注册者却啥也不知道,所以小y打算去看看注册数字杭电的创始人的邮箱
flag形式为:flag{你找到的电子邮箱}
百度一个IP反查询工具,Whois查询,看看这个IP的备案,
0x4 [The world](The World.jpg)
![](The World.jpg)
下载得到一张图,猜测是隐写,直接foremost分解,得到四张图,
第一张是可见的,应该没用,剩下来的,按顺序看。
第一份压缩包是加密压缩包,看了一下不是伪加密,于是放入工具进行简单爆破,得到密码abc123,得到文件:
d2abd3fb9d4c93fb064abf81f5fab84
新手村钥匙
第二份文件是一张图,猜测是LSB隐写,密码为上述字符串,测试后发现不是。继续考虑,可能是### outguess加密,
outguess -r flag.jpg -t secret.txt -k d2abd3fb9d4c93fb064abf81f5fab84
得到文件
95cca6c50e48e86c468ee329ddc11047
最后一关大门的钥匙
第三份文件是一个mp3文件,猜测是MP3隐写,用MP3Stego解密,即可得到flag
0x5 Different_P
hint:PIL是个好东西
下载得到两份一样的文件,试了试盲水印,发现没有用。使用Beyond Compare 4结合后发现
字符这里有点东西。根据题目提示,猜测要将两张图片的所有元素点的灰度拿来作比较,
构造脚本如下
1 | # -*- coding:utf-8 -*- |
得到一张图片,但是打不开,看他的十六进制数据发现文件头被改了。改回来后得到一张二维码,扫码得到flag
Crypto
0x1 easy_RSA
题目文件是public.pem 和 flag.enc,先用openssl打开.pem文件
openssl rsa -pubin -text -modulus -in public.pem
得到
其中。N=>Modulus,e=>Exponent
没有更多信息与算法了,猜测这个大数可以直接分解,上yafu。随后用rsatool生成.pem文件,### 再用openssl解密flag.enc,得到字符串
}Y!s04tEP{ygraCl_f
栅栏加方向即可得到flag,
rsatool和openssl的使用参考
https://www.cnblogs.com/Byqiyou/p/9410885.html
0x2 川流不息
题目加密脚本和密文
加密脚本
1 | from parameters import a |
首先,根据flag前五个字符“flag{”和密文,异或可以得到key的前四十个值,然后爆破得到a
1 | import base64 |
得到a=[1, 0, 0, 1, 0]
然后根据加密脚本,获得key。然后key与密文异或得到flag
1 | def stream(init,size): |
WEB
0x1 base_1
1 | 输入 |
0x2 truncation
进入网站,f12,发现注释:
进入sorce.php发现源码:
1 | <?php |
先进入click.php,发现:flag is not here, and flag in flag.php 得到了flag的位置,那么应该是考任意文件包含漏洞
审计代码得到:
要设定page的值,且内容要在whiteList中
mb_substr($page,0,mb_strpos($page.’?’,’?’))
表示截取page中?之前的内容 接着对$page进行一次URLdecode之后,再判断一次。最后file的值为一个字符串 且 checkfile返回真值 就能包含文件file
所以最终payload:
http://47.110.227.208:8003/index.php?file=source.php?../../flag.php
得到一个猜密码的界面
1 | <html> |
需要post一个赋值了的password和一个和服务器时间的值相同的pwd,脚本如下
1 | import requests |
发现无法获得flag,后来发现pwd赋值为空可以获得flag,可能是$_SESSION[‘pwd’]=time();没有执行成功。
0x3 Simple XXE
首先,了解一下XXE,(xml外部实体注入漏洞)
参考文章:https://www.cnblogs.com/cui0x01/p/8823690.html
(然后跟这个文章走2333)
首先f12看到dom.php存在XXE,于是构造XML文本先验证漏洞,
这一步骤将XML内容发送给服务器,当服务器将XML解析完成后,就会依照解析的内容工作,这段XML中SYSTEM "file:///etc/passwd"部分引用了目标服务器(即172.16.12.2)下的/etc/passwd文件,服务器解析XML内容后,会将这一文件内容存入&xxe中,然后将数据返回给恶意访问者。
执行完成上面的操作后,点击GO,右侧将出现此数据包的返回结果,内容如下,返回的数据为服务器上/etc/passwd文件的内容
漏洞验证成功
于是修改XML中的外部实体为其他协议,根据提示看hint,php://filter/read=convert.base64-encode/resource=hint.php,在Proxy选项卡的原数据包中粘贴XML内容,点击FORWARD放行请求,返回的结果
解码后得到目录,
于是
解码得到flag
0x4 inclusion
进入页面,f12,发现注释 phpinfo.php
然后根据名字,猜测是php文件包含漏洞(利用phpinfo)
参考这篇文章(又是跟着文章走)https://www.cnblogs.com/xiaoqiyue/p/10158702.html
访问http://47.110.227.208:8001/lfi.php?file=/etc/passwd验证漏洞
成功。
文章如是说:
先讲一下利用phpinfo上传文件,然后在文件包含的原理:
参考链接:https://github.com/vulhub/vulhub/tree/master/php/inclusion
在给PHP发送POST数据包时,如果数据包里包含文件区块,无论访问的代码中是否有处理文件上传的逻辑,php都会将这个文件保存成一个临时文件(通常是/tmp/php[6个随机字符]),这个临时文件在请求结束后就会被删除,同时,phpinfo页面会将当前请求上下文中所有变量都打印出来。但是文件包含漏洞和phpinfo页面通常是两个页面,理论上我们需要先发送数据包给phpinfo页面,然后从返回页面中匹配出临时文件名,将这个文件名发送给文件包含漏洞页面。
因为在第一个请求结束时,临时文件就会被删除,第二个请求就无法进行包含。
但是这并不代表我们没有办法去利用这点上传恶意文件,只要发送足够多的数据,让页面还未反应过来,就上传我们的恶意文件,然后文件包含:
1)发送包含了webshell的上传数据包给phpinfo,这个数据包的header,get等位置一定要塞满垃圾数据;
2)phpinfo这时会将所有数据都打印出来,其中的垃圾数据会将phpinfo撑得非常大
3)PHP默认缓冲区大小是4096,即PHP每次返回4096个字节给socket连接
4)所以,我们直接操作原生socket,每次读取4096个字节,只要读取到的字符里包含临时文件名,就立即发送第二个数据包
5)此时,第一个数据包的socket连接其实还没有结束,但是PHP还在继续每次输出4096个字节,所以临时文件还未被删除
6)我们可以利用这个时间差,成功包含临时文件,最后getshell
利用脚本
1 | #!/usr/bin/python |
运行脚本
(表示后来没有上传成功,但似乎有大佬先上传成功了,所以后面的步骤我也能继续做)
先验证是否上传成功
嗯,的确有大佬上传成功了,连文件名也一样,好的,谢谢了。getsheell
于是
flag应该在那个奇怪名字的文件里吧
果然,
拿到flag
这题的关键还是上传有大量垃圾数据的恶意文件吧。(所以哪位大佬上传成功了)
RE
0x1 Secret
(emmm这一题偷懒了),
首先分析主函数
里面有两个check函数。进入checktime()函数,关键代码是这里,
1 | *(&v5 + i) = rand(); |
再加上用来取值的table 123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxy
意识到这是可能是个改变密码表的base58编码变形,于是偷懒,百度找了一个base58的编码解码脚本,改变密码表,
1 | <?php |
解码得到
sEcondBe5tTime1s_n0w}
flag到手
后来发现,那这程序去运行,只要flag的后面一半,也能过,所以一开始其实是忽略了这个check time()函数。。。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 咲夜南梦's 博客!
评论