上周去北京打XCTF-Final,被各位大哥打到自闭。第一天长者复读了一道攻防pwn题,我做另一个带密码学的攻防pwn题,看了下流量,回到宾馆后终于调了出来。题目质量还不错,感谢JHSN和Cyrus的帮助,以下是wp。

Railgun

You can get the binary from here

程序主要的逻辑是一个挖coin然后使用railgun发射coin来打boss的游戏。(强行睿智

menu

程序初始化会将flag+padding用随机生成的RSA公钥加密。每一个Boss都是一个随机的AES key,用一个coin打败Boss并再使用一个coin可以得到用RSA私钥解密用户输入并用AES_ECB加密RSA结果的最后半字节。
在这个过程中用户已知的变量有n, e, pow(flag+padding, e, n)。

UAF

程序在功能6 accelerator attack中可以消耗200个coin直接击败Boss9,这里存在一个UAF。Boss9在被free掉之后依然可以和正常的Boss一样被打败然后进行AES_ECB加密。

UAF

Bypass AES_ecb

利用accelerator attack中的UAF,再利用comment功能,指定注释长度为16就可以malloc到之前free掉的Boss9,这样就可以控制一个AES key。

comment

RSA LSB Oracle Attack

之后进入密码学时间

已知n, e
flag_cipher = pow(flag+padding, e, n)

击杀Boss可以获得
AES_ecb(pow(input, d, n) % 16, Boss)

因为Boss9已经被控制了,所以相当于返回的是pow(input, d, n) % 16

使用RSA LSB Oracle Attack
假设攻击者已知x个最后半字节,设未知部分为a,已知部分是b,则有f = a * 16^{x} + b
y = 16^{-x}\ mod\ n, Y = y^{e}\ mod\ n
输入flag_cipher * Y, 则会返回fy = a + b * 16^{-x}\ mod\ n\ mod\ 16
因为b * 16^{-x}\ mod\ 16已知,所以可以求出a\ mod\ 16

Exploit

利用UAF控制Boss9的内容,然后用RSA LSB Oracle Attack逐半字节攻击出flag

Trick

  • 程序中存在一个检查不严格导致的整数下溢,当你拥有一个coin时对一个Boss连续使用两个coins可以使你的coin数下溢变成255,并且只要你两个两个的用,硬币就永远都用不完。这个trick可以极大的加速你的攻击脚本。(毕竟是个攻防题
  • 在远端利用UAF时,由于环境因素,在执行comment中的malloc时,即使大小合适,也不一定能每次都拿到Boss9的那个块(虽然在本地测试的时候几乎每次都能通)。所以建议多comment几次来提高成功率。(连续申请十次的话基本每次都能通的)