Github Page 加速
快快快,冲冲冲~
快快快,冲冲冲~
WMCTF is a Jeopardy-style Online Capture The Flag Competition presented by W&M. 以下是 0x401 Team 总结整理的 WP。
0x401战队招收各个方向的选手,欢迎投递简历至[email protected]!
PWN
- mengyedekending程序逻辑在so里面,是个.net,反编译一看洞很明显。但是需要覆盖的位置和大小都和反编译出来不太一样。估计是解释器后端内存布局和c有些不同。所以手动测测偏移,发现108偏移就是需要写的位置,写成那个变量的地址即可。
1from pwn import*前面是个迷宫问题,写个广搜搜一搜就可以。最后输入有溢出,ida找字符串,找到关键逻辑位置,可以看到大概就是会覆盖一个地址可以用来泄露,同时可以覆盖返回地址低位。于是第一次覆盖的时候覆盖泄露地址为 go 语言 mmap 出来的一块区域(0xc000000000),可以泄露 程序基地址,同时返回地址最低位改成'\xce'重启该函数。
用这种方式第一次泄露基地址,第二次泄露libc,第三次get shell。可能因为网络原因要多跑几次。
1from pwn import *程序大致逻辑就是服务器模式会hash时间然后用hash值创管道。客户机模式可以用这个hash值连上服务器和服务器通信。漏洞同时在客户机模式和服务机模式的最后。
这里有洞。在有tachebin情况下,malloc(0)会返回0x20的chunk(不确定在2.23情况会怎么样)。于是后面就可以直接堆溢出。
虽然客户机模式的代码也有这个洞,但是客户机模式是子线程,走的不是 main_arena,所以就不用客户机模式来打,打服务器模式的主线程就可以了。
于是在逆向交互逻辑之后,这题就变成了一个堆溢出的题了,大致关键就是把前面已经释放的堆的 size 给改掉,然后后面重新 malloc 再 free 堆就乱了。排布一下堆可以造libc地址和泄露heap地址,最后 tcachebin attack 打free_hook改成puts函数地址(因为开了沙箱,不能直接改system,这里改成puts目的是为了改成一个无害的函数,防止后面free的时候crash),同时另一个堆先在tcahce的 metadata堆占个坑。后面就可以改metadata堆泄露libc,然后泄露栈地址,最后rop。网络原因,可能要多跑几次。
1from pwn import *程序逻辑就是可以溢出0x10字节一次。之前也不熟悉mac,google搜了下找了些资料。
参考资料链接:https://blog.shpik.kr/2019/OSX_Heap_Exploitation/
mac tinybin 在free后会在前两个内存放 pre 指针和 next 指针,存的方式是 addr>>4,之后高4 bit会存一个checksum用来验证。貌似tinybin唯一验证就是只检查这个checksum,然后 checksum 只有4bit, 所以完全可以爆破。
程序的16bit溢出刚好就可以改下一个被释放的堆的 pre 和 next 指针。unlink时候只会执行 next->pre = ptr->pre,于是按照上面的说法,第一个空间改成 value,第二空间改成target addr>>4(高4位随便一个值,反正要爆破),就可以通过unlink将 heap_list 的一个地址给改成got表地址。
但是实际测试的时候发现mac的堆分配很随机,每次分配用的region都是随机的。但是问题不大,只要分配和释放的堆足够多,总有一次触发unlink,并且通过1/16的爆破。
所以大概就是unlink把15号堆地址改成atoi_got。提前在15号堆里面写好一个字符串,每次重新malloc的时候就检查这个字符串有无变化,如果变了的话就说明unlink成功,15号堆地址被改成atoi_got了。后面就可以把atoi_got改成system地址拿flag了。
Web
- webweb__destruct -> __call
$this->db->quotekey($key)这里进行RCE
1<?php经过一堆测试,发现flag居然就在/flag,一读就有
- Make PHP Great Again猜测是通过PHP_SESSION_UPLOAD_PROGRESS可控进行的。参考连接:https://zhuanlan.zhihu.com/p/139229792给出了exp,但是测试发现cookies并没有存放在exp给的路径(因为没包含到会500,包含到了是200),于是一番探寻,发现cookies存在/tmp/下面
首先写个shell。
接着再连接shell在/var/www/html/flag.php找到flag
和 web_checkin1 不同这次flag不在/flag了,于是需要真的把shell写进去然后包含,本想要string.strip_tags结果由于php7.0的缺陷,会导致segmentation_fault,导致写入失败。想来想去还是得利用php filter的特性来搞。对stream_get_filters的结果翻了又翻,发现还有个用于压缩和解压的zlib流,但是zlib压缩解压对数据都是一样的效果,所以还需要搞点事情,让前面的“死亡exit”被破坏掉。我们经过测试发现string.tolower可以让数据部分破坏,但是我们可以精心fuzz出一个结果,让我们的shell即使经过这个过程也依旧能够执行。
最后我们写shell的payload如下
1php://filter/write=zlib.deflate|string.tolower|zlib.inflate/resource=<?PHP eval( $_GET[a ] )?>这个payload会生成一个叫做的shell,但是里面的a被弄成了c。于是首先写入shell(写wp时发现国内外的题目服务器都500了,拿自己的来)
然后包含这个shell,get参数c里面填入想执行的代码(末尾加上exit();防止shell被写入)即可RCE,最后flag在根目录里一个奇形怪状的文件里面
Crypto
- piece_of_cake这题用了个投机的做法,绕开了出题人精心设置的难题。本来审计代码发现,应该是要通过 make_cake 函数去求解未知参数e,但是在我实际对函数 make_cake 进行测试的时候发现,由于每次服务器会自动生成数据,而且没有对数据进行特别严格的检查,所以可以不断地请求数据,直到请求出一组特定的数据,使原问题一个较为简单的二维 NTRU 问题。在验证函数 eat_cake 中,也有类似的二维 NTRU 问题,因此可以直接不停的请求 eat_cake 的数据,直到一组能解的为止。(可以选择多线程池的请求以及自动化的数据筛选)
下图是原问题中二维NTRU的一个典型实现,其中f,g是私钥。通过多次的测试和规约,直到解出两个均为正数的f,g,并且轻松地求出cake,提交就能获得flag。二维NTRU的解法很简单,构造格[1,h][0,p],使用高斯规约或者直接LLL/BKZ规约即可求解SVP。
至于正解,一直没时间想,比赛结束以后可以思考思考。
- babySum120维的子集和问题,给了汉明距离k,其中k远小于维数的一半,密度也比较低,这种情况被称为低密度低重量不平衡背包。由于k较小,解集中大多数都是0,可以随机指定一些位置为0,使这些维不参与实际的运算,达到降维的目的。在这个题目中,随机删除的位置数是15,使用的格是
1import random和上面那题差不多,解法也基本一样,但是维数从120增加到了180。维度扩张以后,BKZ算法求解SVP问题的成功率大大下降,这就不是一般的计算机能计算的问题了。在这个问题中,我选择随机删除40个位置,降到140维,然后租用了一个80核的腾讯云服务器,开了80个进程同时跑,在运算了不知多少个小时以后(大概10h),它跑出了结果。用下图记录这一经典的时刻:
- Game一个逐位爆破的题,主要考察分组密码的模式。在这里我们知道了初始IV,因此可以预测每一次加密中的IV值,然后secret是48个字节,只需要填充47,46,45….位,得到一个加密结果,然后再从0x00到0xff逐位爆破,并与第一次加密结果对比,如果相同则说明这一位猜测正确了。用这种方法可以慢慢地,每一位每一位地搞出所有的位。另外记录一下解题中遇到的bug,由于我在填充的时候一开始加了已爆出的secret位,导致每次都只能爆出相同的第一位,卡了好久才想明白为什么…另,这题似乎还是从实战中TLS改编而来。
1from hashlib import sha256Reverse
- esay_re此题主要是perl写的一个程序,直接下断点单步跟。就可找到flag。
WMCTF{I_WAnt_dynam1c_F1ag}
首先有个坑,程序读取的是键盘index码,而不是ascii码。在0xb28的Call内读取键盘数据,接着把每个数据加上0x55,并按照列优先填充至一个6*6的数组。再跳转至0x6000,再按照行优先每4个一组解析成9个int类型,进行一系列运算,最后和0x5700的常量进行比较。
1import z3程序的逻辑是,读入wav音频文件,提取MFCC特征,把MFCC特征输入网络,网络得到分类结果。所以这题的目的就是生成其他三个方向(左右下)的音频,这个音频需满足:1. 与原音频MFCC特征的平均绝对误差小于4。2.分类的可信度大于0.9。
首先使用:
输出网络结构:
原网络就是一个简单的全连接网络,根据以上两个要求,在原基础搭建新的网络。
1base_model = keras.models.load_model('model.h5')网络结构如下:
sequential层需冻结,所以可训练参数就是两个全连接层:2(2020+20)=840。
网络输入是原音频MFCC特征,经过两个全连接变换后的输出即是我们要拟合的其他方向的MFCC特征,接着把这个特征输入到两个输出层:左边的sequential即原网络满足条件2,loss使用交叉熵categorical_crossentropy、右边的substract,用拟合的MFCC-原音频MFCC,这个结果趋近0(也可以直接输出拟合的MFCC,最后使得结果趋近原音频MFCC即可)就满足条件1,loss使用均方误差mean_squared_error。
训练的时候,input就是example.wav的mfcc,output1是对应方向的one-hot表示、output2是shape = [?,30,20] 的全 0 tensor。
如,right方向训练:
最后把mfcc特征转换成时域的音频信号得到各个方向的音频文件,再使用这些音频文件走到终点即可。
1mfcc1 = get_wav_mfcc('example.wav')12sf.write('sound/down.wav', x, 16000, subtype='PCM_24')
FeedBack
问卷送分题,没啥好写。
- Signin签到题
- XMAN_Happy_birthday!看文件名就知道是反序列输出HEX
xxd -i命令输出C代码
然后编写python脚本进行反序列输出
打开即可得到flag。
- Music_game用标准的美式发音控制up,down,left,right,坦克走到终点弹出flag。
突然好奇 argue 原理,于是有了此文
One of the joys of online shopping is instant gratification – your purchases arrive on your doorstep in just a few...
The post Special Delivery: Criminals Posing as Amazon Are Out to Steal User’s Data appeared first on McAfee Blog.