1 |
Hi folks, |
2 |
|
3 |
for your info and decent google ML washing, here is the log of the irc |
4 |
session we had today regarding the introduction of SSXP. |
5 |
|
6 |
It was a successful event, though there was a rather surprising momentum :) |
7 |
|
8 |
Yes, we found a critical bug on x86 but it wasn't my fault. |
9 |
No, it really wasn't, not this time :) |
10 |
|
11 |
I will work on an updated version of SSXP that encodes the stored return |
12 |
address only and fix the bug on x86. |
13 |
|
14 |
Thanks in advance and cheers, |
15 |
|
16 |
Alex |
17 |
|
18 |
|
19 |
> --- Log opened Thu Dec 07 15:19:28 2006 |
20 |
> 15:19 <@pappy-> ssxp: ping |
21 |
> 15:19 <@pappy-> --- Log opened Thu Dec 07 15:19:28 2006 |
22 |
> 15:19 <@pappy-> 15:19 <@pappy-> ssxp: ping |
23 |
> 15:19 <@pappy-> 15:19 <@pappy-> --- Log opened Thu Dec 07 15:19:28 2006 |
24 |
> 15:19 <@pappy-> 15:19 <@pappy-> 15:19 <@pappy-> ssxp: ping |
25 |
> 15:20 <@pappy-> 15:19 <@pappy-> 15:19 <@pappy-> --- Log opened Thu Dec 07 15:19:28 2006 |
26 |
> 15:20 <@pappy-> 15:19 <@pappy-> 15:19 <@pappy-> 15:19 <@pappy-> ssxp: ping |
27 |
> 15:20 <@pappy-> 15:20 <@pappy-> 15:19 <@pappy-> 15:19 <@pappy-> --- Log opened Thu Dec 07 15:19:28 2006 |
28 |
> 15:20 <@pappy-> 15:20 <@pappy-> 15:19 <@pappy-> 15:19 <@pappy-> 15:19 <@pappy-> ssxp: ping |
29 |
> 15:20 < GSF> uh oh |
30 |
> 15:20 <@pappy-> 15:20 <@pappy-> 15:19 <@pappy-> 15:19 <@pappy-> 15:19 <@pappy-> ssxp: ping |
31 |
> 15:20 <@pappy-> 15:20 <@pappy-> 15:20 <@pappy-> 15:19 <@pappy-> 15:19 <@pappy-> --- Log opened Thu Dec 07 15:19:28 2006 |
32 |
> 15:20 <@pappy-> :) |
33 |
> 15:21 < nms> i will be logging as well, so if anyone ends up with incomplete logs for some reason i might have patches :) |
34 |
> 15:22 <@pappy-> tonight the only test system to show stuff is amd64 |
35 |
> 15:22 <@pappy-> the x86 host didnt compile |
36 |
> 15:22 <@pappy-> because of glibc segfaults with gcc-3.4.x |
37 |
> 15:22 <@pappy-> wasn't the fault of ssxp though :) |
38 |
> 15:22 <@pappy-> compiled glibc-2.5 with gcc-3.4.x |
39 |
> 15:22 <@pappy-> didnt like it |
40 |
> 15:24 <@pappy-> i'll try to recompile it on my box again now |
41 |
> 17:08 -!- pappy-_ [n=alex@×××××××××××××××××××××××××××××××××××.net] has joined #ssxp |
42 |
> 17:11 <@ssxp> oops disconnect :) |
43 |
> 17:11 -!- pappy-_ is now known as pap |
44 |
> 17:12 -!- pap is now known as pappy-_ |
45 |
> 17:13 -!- mode/#ssxp [+o pappy-] by ssxp |
46 |
> 17:13 * pappy-_ ponders his nickname |
47 |
> 17:13 -!- mode/#ssxp [+o pappy-_] by ssxp |
48 |
> 17:23 -!- pappy- [n=alex@×××××××××××××××××××××××××××××××××××.net] has quit [Read error: 110 (Connection timed out)] |
49 |
> 17:23 -!- nms_ [n=martin@××××××××××××××××××××××××××××××.com] has joined #ssxp |
50 |
> 17:27 -!- nms [n=martin@×××××××××××××××××××××××××××××.com] has quit [Read error: 145 (Connection timed out)] |
51 |
> 17:37 -!- pappy-_ is now known as pappy- |
52 |
> 17:43 -!- nms_ is now known as nms |
53 |
> 19:02 < codejunky> Ich sitz in Hamburg, also geht das hier um 21:00 los? :) |
54 |
> 19:03 <@ssxp> richtig |
55 |
> 19:03 <@ssxp> date --utc zeigt dir die jeweilige utc zeit gerade |
56 |
> 19:03 < codejunky> Ah okay. |
57 |
> 19:04 < codejunky> Den kannte ich noch nicht ;) |
58 |
> 19:06 -!- ssxp changed the topic of #ssxp to: Stack Smashing XOR Protection (SS(X)P) - welcome to the irc presentation - 20:00 UTC tonight - http://dev.gentoo.org/~pappy/ssxp/ || http://www0.fh-trier.de/~gaberta/ssxp/ || http://user.noxa.de/~pappy/ssxp/ |
59 |
> 19:06 -!- ssxp changed the topic of #ssxp to: Stack Smashing XOR Protection (SS(X)P) - welcome to the irc presentation - 20:00 UTC 21:00 CET tonight - http://dev.gentoo.org/~pappy/ssxp/ || http://www0.fh-trier.de/~gaberta/ssxp/ || http://user.noxa.de/~pappy/ssxp/ |
60 |
> 19:19 < Javi> damn, at 21 I won't be here |
61 |
> 19:21 -!- CHTEKK [n=chtekk@gentoo/developer/chtekk] has joined #ssxp |
62 |
> 19:39 <@ssxp> i can show amd64 and x86 SSXP assembler code tonight |
63 |
> 19:40 <@ssxp> it looks that my x86 chroot is just finishing the gcc installation |
64 |
> 19:43 -!- pipacs [i=theowl@×××××××××.com] has joined #ssxp |
65 |
> 19:44 <@pappy-> hi pipacs |
66 |
> 19:44 <@pappy-> welcome |
67 |
> 19:45 < pipacs> salut |
68 |
> 19:45 <@ssxp> comment allez vous |
69 |
> 20:12 < voidptr> grabbing some smokes, later |
70 |
> 20:27 < voidptr> puuh, bad weather :) |
71 |
> 20:31 -!- Vinky [i=Vinky@gateway/tor/x-7fd72dcccf8a1169] has joined #ssxp |
72 |
> 20:51 -!- ssxp changed the topic of #ssxp to: the next generation of stack protection: Stack Smashing XOR Protection - http://dev.gentoo.org/~pappy/ssxp |
73 |
> 20:56 -!- mode/#ssxp [-o pappy-] by ssxp |
74 |
> 20:59 <@ssxp> hello |
75 |
> 20:59 < pappy-> welcome to my introduction of SSXP the stack smashing xor protection |
76 |
> 20:59 < pappy-> first of all i'd like to introduce myself |
77 |
> 21:00 < pappy-> then give you time for answering initial questions |
78 |
> 21:00 < pappy-> then i present the solution |
79 |
> 21:00 < pappy-> and you can tear it apart then |
80 |
> 21:00 < pappy-> any questions? |
81 |
> 21:01 < pappy-> okay, i'll just start to scroll |
82 |
> 21:01 -!- phreak`` [n=phreak``@gentoo/developer/phreak] has joined #ssxp |
83 |
> 21:02 < pappy-> my name is Alex, i'm one of the developers at Gentoo Hardened doing the hardened toolchain which consists of PIE and SSP code generation |
84 |
> 21:02 < pappy-> i also do grsec and pax kernel |
85 |
> 21:02 < pappy-> and misc stuff like scripts and maintaining, docs and helping users |
86 |
> 21:03 < pappy-> the first steps of the hardened toolchain started in 2003 with a radical change in how we added SSP object code to the userland |
87 |
> 21:03 < pappy-> back this time we decided there should be an automatic way to enable and instrument stack protection on executables automatically during building |
88 |
> 21:04 < pappy-> which later became the all-famous haskell- and assembler- breaking hardened gcc |
89 |
> 21:04 < pappy-> hardened gcc basically is a compiler that's trying to put SSP prologues and epilogues into binaries and libraries |
90 |
> 21:05 < pappy-> and turning executables into position independent executables |
91 |
> 21:06 < pappy-> the reason for this is obvious: position independent executables are more secure because their virtual memory layout allows for the most parts of the process to be unwritable and especially the executable parts unwritable |
92 |
> 21:06 < pappy-> turning the stack nonexecutable then closes another possible way of introducing new executable code |
93 |
> 21:06 < pappy-> this is achieved with using a PaX kernel that not only protects the executable's memory, it also randomizes the process |
94 |
> 21:06 < pappy-> whcih means the libraries and the parts of the executable are randomly organized in memory for each new execution |
95 |
> 21:07 < pappy-> we'll talk about that later (and why it's important) |
96 |
> 21:07 < pappy-> so that's what i do basically |
97 |
> 21:07 < pappy-> anybody having an initial question regarding the function of ssxp and it's design? |
98 |
> 21:09 < pipacs> just a note |
99 |
> 21:09 < pappy-> go ahead |
100 |
> 21:10 < pipacs> we don't use PIEs because it makes w^x easier, as that's true for normal ET_EXEC executables as well after all |
101 |
> 21:10 < pipacs> we use them for the sole purpose to be able to randomize them at runtime |
102 |
> 21:10 < pappy-> and to disable text relocations |
103 |
> 21:10 < pipacs> we don't have textrels in ET_EXEC either ;) |
104 |
> 21:11 < pappy-> understood |
105 |
> 21:11 < pipacs> TEXTRELs come from libs mostly, and PIEs if they're improperly compiled/linked |
106 |
> 21:11 < pipacs> so in fact the introduction of PIEs made it all the more urgent/important to get rid of textrel prone code as much as possible |
107 |
> 21:11 < pipacs> ok, that's all |
108 |
> 21:12 < pappy-> if nobody has a question, i will talk about the history of SSP and it's predecessors and competitors a bit |
109 |
> 21:12 < pappy-> professional readers among you will know the following URL's |
110 |
> 21:12 < pappy-> http://www.phrack.org/archives/55/P55-08 |
111 |
> 21:12 < pappy-> http://www.phrack.org/archives/56/p56-0x05 |
112 |
> 21:13 < pappy-> back when these docs were written, lots of work has been invested in making SSP and other suites bulletproof against these described methods |
113 |
> 21:14 < pappy-> the reordering of variables by SSP is the direct result of the testing and thinking done at these times |
114 |
> 21:14 < pappy-> SSP itself is very mature |
115 |
> 21:15 < pappy-> we are compiling very much packages with it and the only problems so far is C++ code, haskell (erlang) and assembler that modifies stack content. |
116 |
> 21:15 * voidptr nods |
117 |
> 21:15 < pappy-> it is also understandable that the PaX kernel does not "need" SSP |
118 |
> 21:16 < pappy-> SSP itself may be even "inferior" to the model of PaX and it's protections |
119 |
> 21:16 < pappy-> because it can "only" detect data being overwritten on the stack |
120 |
> 21:16 < pappy-> in my understanding, the PaX kernel does not need SSP because even if an attacker can write shellcode to the stack, there is not much left to do because it's nonexecutable |
121 |
> 21:17 < pappy-> also there is work done for PaX userland security stuff (pax-future.txt) |
122 |
> 21:17 < pappy-> which will eventually supercede the work of SSP completely |
123 |
> 21:17 < voidptr> Isn't prevention at that stage not just better? i mean, modifying any kernel data (that is located next to it on the stack) could already give the attacker some benefits |
124 |
> 21:18 < voidptr> although it would only get handled at the function prologue i'm sure. |
125 |
> 21:18 < pappy-> voidptr: every overwrite of critical data that can be prevented should be prevented. |
126 |
> 21:18 < pappy-> if it's SSP preventing it, PaX does not have to kick in later. |
127 |
> 21:18 < pappy-> that's my personal opinion. |
128 |
> 21:18 < pappy-> i know that the PaX team is smiling at this |
129 |
> 21:18 < pappy-> but there is enough room for every solution |
130 |
> 21:19 < pappy-> basically, PaX is effective and "cheap" in terms of cost involved for runtime |
131 |
> 21:19 < pappy-> the same holds true for -fstack-protector and -fstack-protector-all protecting functions with SSP |
132 |
> 21:20 < pappy-> now, thinking it further |
133 |
> 21:20 < pappy-> SSP sets up a guard on the stack |
134 |
> 21:20 < pappy-> but does not protect the integrity of control data |
135 |
> 21:20 < pappy-> control data that's fulfilling some important criterias |
136 |
> 21:20 < pappy-> * it's always there |
137 |
> 21:20 < pappy-> * it's having the same layout in every function stack frame |
138 |
> 21:21 < pappy-> * you can find information about the state of current randomization in it |
139 |
> 21:21 < pappy-> * you can easily use the return address as a jump pad to code you already found out where it is (even with randomization) |
140 |
> 21:21 < pappy-> there have been wu-ftpd exploits where it was possible to read data from a process and after reading write data to the same process |
141 |
> 21:21 < pappy-> you can't rule out that those things do not happen again. |
142 |
> 21:22 < pappy-> so my idea was |
143 |
> 21:22 < pappy-> protect the control data |
144 |
> 21:22 < pappy-> which is not full bounds checking |
145 |
> 21:22 < pappy-> and cannot be |
146 |
> 21:22 < pappy-> because there is a speed vs. protection relationship |
147 |
> 21:22 < pappy-> with full protection you need to sacrifice speed |
148 |
> 21:22 < pappy-> and with speed you cannot have full protection |
149 |
> 21:23 < pappy-> for this reason i decided to use the xor operation because it's fast, effective and it is possible to make it irreversible for an attacker under the following circumstances: |
150 |
> 21:23 < pappy-> * every function in the current process is protected with SSXP |
151 |
> 21:23 < pappy-> * PaX is randomizing the address space |
152 |
> 21:23 < pappy-> * the attacker cannot read the original guard values from glibc |
153 |
> 21:23 < pappy-> however, the attacker can be able to read the stack and write it as she or he wants to |
154 |
> 21:24 < pappy-> in my understanding, using PaX and SSXP improves what PaX and SSP already delivers: |
155 |
> 21:24 < pappy-> a profound base for protecting your machines from future exploit patterns |
156 |
> 21:25 < pappy-> if you have questions i can answer now, otherwise i will show code now |
157 |
> 21:27 < pappy-> the following excerpt from a prologue was generated using SSXP compiler on an intel x86 machina |
158 |
> 21:27 < pappy-> 17 movl %gs:20, %eax |
159 |
> 21:27 < pappy-> 18 movl %eax, -8(%ebp) |
160 |
> 21:27 < pappy-> 19 xorl %eax, %eax |
161 |
> 21:27 < pappy-> if you have questions, please refer to the line numbers pasted leftmost |
162 |
> 21:28 < pappy-> these three lines are the original SSP part of the prologue |
163 |
> 21:28 < pappy-> it means: load the __guard value from %gs:20 into %eax register |
164 |
> 21:28 < pappy-> %gs:20 is a special means of acessing data in the Thread Local Storage |
165 |
> 21:28 < pappy-> do you want to learn about it or are you accustomed to this notation? |
166 |
> 21:28 < pappy-> it'S got something to do with a selector |
167 |
> 21:29 < pappy-> and segmentation based addressing on intel machine |
168 |
> 21:29 < pappy-> you can shout stop if it's going to fast. |
169 |
> 21:29 < pappy-> in line 18 we are moving this __guard original value to the stack slot reserved for the guard |
170 |
> 21:30 < pappy-> in line 19 we are preventing information leak by zeroing out the original guard value |
171 |
> 21:30 < pappy-> which is kind of moot because the guard is on the stack nevertheless in cleartext :) |
172 |
> 21:30 < pappy-> but maybe there were trying to not give the value in a register to an attacker who could possibly do something bad with it |
173 |
> 21:31 < pappy-> 20 movl -8(%ebp), %eax |
174 |
> 21:31 < pappy-> 21 xorl -4(%ebp), %eax |
175 |
> 21:31 < pappy-> 22 movl %eax, -8(%ebp) |
176 |
> 21:31 < pappy-> this code is taking the stored canary (with the guard value) from the stack slot into a register |
177 |
> 21:32 < pappy-> does an xor operation with the saved frame pointer with it |
178 |
> 21:32 < pappy-> and stores the result back in eax |
179 |
> 21:32 < pappy-> which then (line 22) gets stored back in the canary |
180 |
> 21:32 < pappy-> this procedure is described here: http://dev.gentoo.org/~pappy/ssxp/latex2html/node85.html |
181 |
> 21:33 < pappy-> we are currently in the first part of the level1 encoding operation |
182 |
> 21:33 < pappy-> we have done __guard1 xor sfptr == xguard (which is the canary location) |
183 |
> 21:33 < pappy-> 23 movl -8(%ebp), %eax |
184 |
> 21:33 < pappy-> 24 xorl 0(%ebp), %eax |
185 |
> 21:33 < pappy-> 25 movl %eax, -8(%ebp) |
186 |
> 21:33 < pappy-> the next part is with the return address |
187 |
> 21:33 < pappy-> if i'm going to fast or you are already bored: just shout |
188 |
> 21:34 < pappy-> also if you don't understand something, please feel free to disrupt and ask free away! |
189 |
> 21:34 < pappy-> in line 23 we are getting the (this time halfway level1 encoded) canary value again |
190 |
> 21:34 < pappy-> and xor the return address onto it |
191 |
> 21:34 < pappy-> finally in 25 we store it back |
192 |
> 21:34 < pappy-> this finalizes level1 encoding of prologue |
193 |
> 21:34 < pappy-> please notice that gcc -O2 is optimizing this sequence |
194 |
> 21:34 < pipacs> uhm, wait a sec |
195 |
> 21:35 < pappy-> you don't need to think this is hardcoded assembler |
196 |
> 21:35 < pipacs> are you sure the ebp offsets are fine? |
197 |
> 21:35 < pappy-> pipacs: i guess so |
198 |
> 21:35 < pappy-> pipacs: it's intel assembler |
199 |
> 21:35 < pipacs> normally the prologue has: push ebp, mov ebp,esp -> saved eip is at ebp+4, saved ebp is at ebp+0 |
200 |
> 21:35 < pipacs> i.e. 4 bytes higher than what you showed us |
201 |
> 21:37 < pappy-> rtx sfptr = gen_rtx_MEM (mode, frame_pointer_rtx); |
202 |
> 21:37 < pipacs> if the quoted code was actually compiler generated, can you show the full prologue? |
203 |
> 21:37 < pipacs> maybe there's something else done to the stack than what is usual |
204 |
> 21:37 < pappy-> rtx retaddr = gen_rtx_MEM (mode, gen_rtx_PLUS (mode, frame_pointer_rtx, GEN_INT (GET_MODE_SIZE (mode)))); |
205 |
> 21:37 < pappy-> 1 .file "vuln-stack.c" |
206 |
> 21:37 < pappy-> 2 .text |
207 |
> 21:37 < pappy-> 3 .globl main |
208 |
> 21:37 < pappy-> 4 .type main, @function |
209 |
> 21:37 < pappy-> 5 main: |
210 |
> 21:37 < pappy-> 6 leal 4(%esp), %ecx |
211 |
> 21:37 < pappy-> 7 andl $-16, %esp |
212 |
> 21:37 < pappy-> 8 pushl -4(%ecx) |
213 |
> 21:37 < pappy-> 9 pushl %ebp |
214 |
> 21:37 < pappy-> 10 movl %esp, %ebp |
215 |
> 21:37 < pappy-> 11 pushl %ecx |
216 |
> 21:38 < pappy-> 12 subl $36, %esp |
217 |
> 21:38 < pappy-> 13 movl (%ecx), %eax |
218 |
> 21:38 < pappy-> 14 movl %eax, -24(%ebp) |
219 |
> 21:38 < pappy-> 15 movl 4(%ecx), %eax |
220 |
> 21:38 < pappy-> 16 movl %eax, -28(%ebp) |
221 |
> 21:38 < pappy-> 17 movl %gs:20, %eax |
222 |
> 21:38 < pappy-> 18 movl %eax, -8(%ebp) |
223 |
> 21:38 < pappy-> 19 xorl %eax, %eax |
224 |
> 21:38 < pappy-> 20 movl -8(%ebp), %eax |
225 |
> 21:38 < pappy-> 21 xorl -4(%ebp), %eax |
226 |
> 21:38 < pappy-> 22 movl %eax, -8(%ebp) |
227 |
> 21:38 < pappy-> 23 movl -8(%ebp), %eax |
228 |
> 21:38 < pappy-> 24 xorl 0(%ebp), %eax |
229 |
> 21:38 < pappy-> 25 movl %eax, -8(%ebp) |
230 |
> 21:38 < pappy-> 26 movl __stack_chk_fguard, %eax |
231 |
> 21:38 < pappy-> 27 xorl -4(%ebp), %eax |
232 |
> 21:38 < pappy-> 28 movl %eax, -4(%ebp) |
233 |
> 21:38 < pappy-> 29 movl __stack_chk_rguard, %eax |
234 |
> 21:38 < pappy-> 30 xorl 0(%ebp), %eax |
235 |
> 21:38 < pappy-> 31 movl %eax, 0(%ebp) |
236 |
> 21:38 < pappy-> 32 movl -28(%ebp), %eax |
237 |
> 21:39 < pappy-> 31 is the last instruction of SSXP prologue |
238 |
> 21:39 < pipacs> i understand but |
239 |
> 21:39 < pipacs> where is -4(%ebp) written to first? |
240 |
> 21:40 < pipacs> pushl -4(%ecx) ensures that the saved eip is just above the saved frame ptr, so far so good |
241 |
> 21:40 < pipacs> which makes my maths still correct |
242 |
> 21:40 < pappy-> pipacs: i will start gdb for you |
243 |
> 21:40 < pipacs> but the only thing i see is a read from -4(ebp), w/o it having been ever written to |
244 |
> 21:40 < pappy-> just tell me what you want to do |
245 |
> 21:41 < pipacs> just trace until line 21 above |
246 |
> 21:41 < pipacs> and dump the stack from ebp-8 |
247 |
> 21:41 < pappy-> ssxp@apocalypse ~ $ gcc -fPIE -o vuln-stack vuln-stack.c; /sbin/paxctl -pemsrx vuln-stack; gdb --quiet --args ./vuln-stack AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA |
248 |
> 21:41 < pappy-> 0x080484c5 <main+49>: xor %eax,%eax |
249 |
> 21:41 < pappy-> 0x080484c7 <main+51>: mov 0xfffffff4(%ebp),%eax |
250 |
> 21:41 < pappy-> 0x080484ca <main+54>: xor 0xfffffff8(%ebp),%eax |
251 |
> 21:42 < pipacs> (paxctl -mr is normally enough btw ;-) |
252 |
> 21:42 < pappy-> i will single step to 0x080484ca |
253 |
> 21:42 < pipacs> first x/8x $ebp-8 |
254 |
> 21:42 < pappy-> 0x080484ca in main () |
255 |
> 21:42 < pappy-> we are before the instruction xor 0xfffffff8(%ebp),%eax |
256 |
> 21:42 < pappy-> it is not yet executed |
257 |
> 21:42 < pipacs> it's ok |
258 |
> 21:43 < pappy-> (gdb) x/8x $ebp-8 |
259 |
> 21:43 < pappy-> 0xbfc859c0: 0xbfc859e0 0xb7f6aff4 0xbfc85a08 0xb7e66d70 |
260 |
> 21:43 < pappy-> 0xbfc859d0: 0x08048570 0xb7f8eca0 0xbfc85a08 0xb7e66d70 |
261 |
> 21:43 < pipacs> and x/i 0xb7f6aff4 ? |
262 |
> 21:43 < pappy-> (gdb) x/i 0xb7f6aff4 |
263 |
> 21:43 < pappy-> 0xb7f6aff4 <_IO_file_jumps+1556>: jl 0xb7f6af93 <_IO_file_jumps+1459> |
264 |
> 21:44 < pipacs> see, that's supposed to be the caller of 'main' |
265 |
> 21:44 < pipacs> somewhere in libc presumably |
266 |
> 21:44 < pappy-> well, i am generating the address this way: |
267 |
> 21:44 < pipacs> but it's some unrelated 'code', probably not even in an executable area but some data |
268 |
> 21:44 < pappy-> rtx sfptr = gen_rtx_MEM (mode, frame_pointer_rtx); |
269 |
> 21:44 < pipacs> that generated proper asm as far as i see |
270 |
> 21:44 < pappy-> which boils down to the memory location of the saved frame pointer |
271 |
> 21:45 < pappy-> adding a pointer wide to it yields the return address |
272 |
> 21:45 < pipacs> err, actually, no |
273 |
> 21:45 < pappy-> rtx retaddr = gen_rtx_MEM (mode, gen_rtx_PLUS (mode, frame_pointer_rtx, GEN_INT (GET_MODE_SIZE (mode)))); |
274 |
> 21:45 < pipacs> it's off by 4 as well |
275 |
> 21:45 < pipacs> you're missing an offset of 4 in your calculations somehow |
276 |
> 21:45 < pipacs> for both the saved ebp and eip |
277 |
> 21:46 < pipacs> i don't know gcc rtl syntax to help you unfortunately |
278 |
> 21:46 < pappy-> well, rtl syntax is easy |
279 |
> 21:46 < pipacs> but the asm speaks for itself and you can see it from the stack dump as well |
280 |
> 21:46 < pappy-> frame_pointer_rtx describes the memory location |
281 |
> 21:47 < pipacs> there's a gcc intrinsic called __builtin_return_address() or something like that, can you check what it's defined as for i386? |
282 |
> 21:47 < pipacs> 'cos it's supposed to do the same access for the saved eip as you try to |
283 |
> 21:47 < pipacs> therefore i assume it does the proper calculation already |
284 |
> 21:47 < pipacs> anyway, don't let me hold you up, this is a bug you can fix later |
285 |
> 21:48 < pappy-> well we can look at it now |
286 |
> 21:48 < pappy-> i'm grateful for your eagle eyes |
287 |
> 21:48 < pappy-> error: too few arguments to function '__builtin_return_address |
288 |
> 21:49 < pipacs> pass a 0 for the current frame |
289 |
> 21:49 < pipacs> (it can look up the return addr in higher frames as well, but i think it needs frame ptr for that) |
290 |
> 21:50 < pappy-> #include <stdio.h> |
291 |
> 21:50 < pappy-> int main(void) { |
292 |
> 21:50 < pappy-> __builtin_return_address(0); |
293 |
> 21:50 < pappy-> } |
294 |
> 21:50 < pappy-> main: |
295 |
> 21:50 < pappy-> leal 4(%esp), %ecx |
296 |
> 21:50 < pappy-> andl $-16, %esp |
297 |
> 21:50 < pappy-> pushl -4(%ecx) |
298 |
> 21:50 < pappy-> pushl %ebp |
299 |
> 21:50 < pappy-> movl %esp, %ebp |
300 |
> 21:50 < pappy-> pushl %ecx |
301 |
> 21:50 < pappy-> popl %ecx |
302 |
> 21:50 < pappy-> popl %ebp |
303 |
> 21:50 < pappy-> leal -4(%ecx), %esp |
304 |
> 21:50 < pappy-> ret |
305 |
> 21:50 < pipacs> that's a bit too much optmized ;) |
306 |
> 21:51 < pipacs> write it into a global variable |
307 |
> 21:51 < pappy-> int main(void) { |
308 |
> 21:51 < pappy-> printf("%x\n", __builtin_return_address(0)); |
309 |
> 21:51 < pappy-> leal 4(%esp), %ecx |
310 |
> 21:51 < pappy-> andl $-16, %esp |
311 |
> 21:51 < pappy-> pushl -4(%ecx) |
312 |
> 21:51 < pappy-> pushl %ebp |
313 |
> 21:51 < pappy-> movl %esp, %ebp |
314 |
> 21:51 < pappy-> pushl %ecx |
315 |
> 21:51 < pappy-> subl $20, %esp |
316 |
> 21:51 < pappy-> movl 4(%ebp), %eax |
317 |
> 21:51 < pappy-> movl %eax, 4(%esp) |
318 |
> 21:51 < pappy-> movl $.LC0, (%esp) |
319 |
> 21:51 < pappy-> call printf |
320 |
> 21:51 < pappy-> addl $20, %esp |
321 |
> 21:51 < pipacs> see the movl 4(%ebp), %eax ? |
322 |
> 21:51 < pappy-> popl %ecx |
323 |
> 21:51 < pappy-> popl %ebp |
324 |
> 21:51 < pappy-> leal -4(%ecx), %esp |
325 |
> 21:51 < pappy-> ret |
326 |
> 21:51 < pappy-> yeah, you're right |
327 |
> 21:51 < pipacs> that's the +4 as it should be |
328 |
> 21:51 < pappy-> it's 4(%ebp) |
329 |
> 21:52 < pappy-> i see |
330 |
> 21:52 < pappy-> but then i don't understand the frame_pointer_rtx |
331 |
> 21:52 < pappy-> why it's showing the wrong location |
332 |
> 21:52 < pipacs> maybe you're supposed to re-bias it yourself |
333 |
> 21:52 < pappy-> rebias? |
334 |
> 21:52 < pipacs> that's why i told you to check the gcc sources |
335 |
> 21:52 < pipacs> well add 4 explicitly or something to that effect |
336 |
> 21:52 < pappy-> i see |
337 |
> 21:53 < pappy-> add pointerwidth |
338 |
> 21:53 < pappy-> to make it machine independent |
339 |
> 21:53 < pipacs> or even +8 if i'm not mistaken |
340 |
> 21:53 < pipacs> since you had -8/-4 vs 0/4 |
341 |
> 21:53 < pappy-> well -8 was the canary |
342 |
> 21:54 < pappy-> and -4 was the frame pointer stored |
343 |
> 21:54 < pappy-> and 0 was the saved return address |
344 |
> 21:54 < pipacs> ok, +4 it is then |
345 |
> 21:55 < pipacs> i wonder, maybe frame_pointer_rtx is a ptr/reference to the first free slot *below* the saved ebp |
346 |
> 21:55 < pipacs> is there some doc about it? |
347 |
> 21:55 < pappy-> 17 movl %gs:20, %eax |
348 |
> 21:55 < pappy-> 18 movl %eax, -8(%ebp) |
349 |
> 21:55 < pappy-> this is moving the 32bit value (4byte) to -8 |
350 |
> 21:55 < pappy-> which leaves the saved frame pointer at -4 |
351 |
> 21:55 < pappy-> which leaves the retaddr at 0 |
352 |
> 21:56 < pappy-> pipacs: i had tests running that showed me that i was in fact encoding and decoding the return address and saved frame pointer |
353 |
> 21:56 < pappy-> but i will double check and send you mail with output |
354 |
> 21:56 < pappy-> so you can see for yourself |
355 |
> 21:56 < pipacs> well, you can see that what you take as return address is not |
356 |
> 21:56 < pipacs> maybe your stack dump was off by 4 as well :) |
357 |
> 21:56 < pappy-> it was gdb |
358 |
> 21:57 < pappy-> movl 4(%ebp), %eax |
359 |
> 21:57 < pappy-> this one is making me wonder |
360 |
> 21:57 < pappy-> i'll research it :) |
361 |
> 21:57 < pappy-> back to topic |
362 |
> 21:58 < pappy-> now let's assume the problems are fixed and we are encoding the return address and saved frame pointer |
363 |
> 21:58 < pipacs> sure |
364 |
> 21:58 < pappy-> which means an attacker can read the stack |
365 |
> 21:58 < pappy-> and will get the values |
366 |
> 21:58 < pappy-> now, in an nonrandomized setup |
367 |
> 21:58 < pappy-> the attacker can easily revert the retrieved values to the original values |
368 |
> 21:58 < pappy-> because he or she will usually know the target (or be local on the machine) |
369 |
> 21:59 < pappy-> http://dev.gentoo.org/~pappy/ssxp/latex2html/node98.html |
370 |
> 21:59 < pappy-> which means when the original return address is known |
371 |
> 21:59 < pappy-> and the original saved frame pointer |
372 |
> 21:59 < pappy-> the attacker can simply read the stack |
373 |
> 21:59 < pappy-> and recompute the xor operation |
374 |
> 21:59 < pappy-> which makes it necessary to randomize the process for SSXP to have any valueable effect |
375 |
> 21:59 < pappy-> otherwise, if you dont randomize you can use SSXP only for integrity checking |
376 |
> 22:00 < pappy-> but if you have information leaking and the attacker knows the original values, the concept is worthless and falls down to the normal SSP behaviour |
377 |
> 22:00 < pappy-> which means linear reading, linear writing is possible to override the protection |
378 |
> 22:00 < pappy-> just read the stack, fix up the values, write it back |
379 |
> 22:00 < pappy-> there is no encryption done |
380 |
> 22:00 < pappy-> it's only a simple mathematical operation everybody can recreate |
381 |
> 22:01 < pappy-> so, when using SSXP with process randomization, we are preventing the control data to be modified. |
382 |
> 22:01 < pappy-> or in this case data -4 bytes below our control data. |
383 |
> 22:01 < pappy-> *g* |
384 |
> 22:01 < pappy-> any questions? |
385 |
> 22:03 < pappy-> movq 8(%rbp), %rax |
386 |
> 22:03 < pappy-> pipacs: this is amd64 |
387 |
> 22:03 < pipacs> +8 for retaddr? |
388 |
> 22:03 < pappy-> 15 movq %fs:40, %rax |
389 |
> 22:03 < pappy-> 16 movq %rax, -8(%rbp) |
390 |
> 22:03 < pappy-> 17 xorl %eax, %eax |
391 |
> 22:04 < pappy-> 18 movq -8(%rbp), %rax |
392 |
> 22:04 < pappy-> 19 xorq 0(%rbp), %rax |
393 |
> 22:04 < pappy-> 20 movq %rax, -8(%rbp) |
394 |
> 22:04 < pappy-> 21 movq -8(%rbp), %rax |
395 |
> 22:04 < pappy-> the 22 xorq 8(%rbp), %rax |
396 |
> 22:04 < pappy-> 23 movq %rax, -8(%rbp) |
397 |
> 22:04 < pipacs> -8/0 vs 0/8 i think |
398 |
> 22:04 < pipacs> same problem |
399 |
> 22:04 < pipacs> ah, 0/8 |
400 |
> 22:04 < pipacs> that seems better |
401 |
> 22:04 < pappy-> pipacs: it's the same patch |
402 |
> 22:04 < pappy-> exactly the same patch |
403 |
> 22:05 < pipacs> you're still off by 4 on i386 as far as i see it though |
404 |
> 22:05 < pappy-> yeah you're absolutely right |
405 |
> 22:05 < pipacs> actually, can you show me the full prologue on amd64? |
406 |
> 22:05 < pappy-> 3 .globl main |
407 |
> 22:05 < pappy-> 4 .type main, @function |
408 |
> 22:05 < pappy-> 5 main: |
409 |
> 22:05 < pappy-> 6 .LFB2: |
410 |
> 22:05 < pappy-> 7 pushq %rbp |
411 |
> 22:05 < pappy-> 8 .LCFI0: |
412 |
> 22:05 < pappy-> 9 movq %rsp, %rbp |
413 |
> 22:05 < pappy-> 10 .LCFI1: |
414 |
> 22:05 < pappy-> 11 subq $48, %rsp |
415 |
> 22:05 < pappy-> 12 .LCFI2: |
416 |
> 22:05 < pappy-> 13 movl %edi, -36(%rbp) |
417 |
> 22:05 < pappy-> 14 movq %rsi, -48(%rbp) |
418 |
> 22:05 < pappy-> 15 movq %fs:40, %rax |
419 |
> 22:06 < pappy-> 16 movq %rax, -8(%rbp) |
420 |
> 22:06 < pappy-> 17 xorl %eax, %eax |
421 |
> 22:06 < pappy-> 18 movq -8(%rbp), %rax |
422 |
> 22:06 < pappy-> 19 xorq 0(%rbp), %rax |
423 |
> 22:06 < pappy-> 20 movq %rax, -8(%rbp) |
424 |
> 22:06 < pappy-> 21 movq -8(%rbp), %rax |
425 |
> 22:06 < pappy-> 22 xorq 8(%rbp), %rax |
426 |
> 22:06 < pappy-> 23 movq %rax, -8(%rbp) |
427 |
> 22:06 < pappy-> 24 movq __stack_chk_fguard(%rip), %rax |
428 |
> 22:06 < pappy-> 25 xorq 0(%rbp), %rax |
429 |
> 22:06 < pappy-> 26 movq %rax, 0(%rbp) |
430 |
> 22:06 < pappy-> 27 movq __stack_chk_rguard(%rip), %rax |
431 |
> 22:06 < pappy-> 28 xorq 8(%rbp), %rax |
432 |
> 22:06 < pappy-> 29 movq %rax, 8(%rbp) |
433 |
> 22:06 < pappy-> 30 movq -48(%rbp), %rax |
434 |
> 22:06 < pappy-> 31 addq $8, %rax |
435 |
> 22:06 < pappy-> 32 movq (%rax), %rsi |
436 |
> 22:06 < pappy-> 33 leaq -32(%rbp), %rdi |
437 |
> 22:06 < pappy-> 34 call strcpy |
438 |
> 22:06 < pappy-> 35 movl $0, %eax |
439 |
> 22:06 < pappy-> rguard is the guard responsible for triggering the level2 encoding of the stored return address in place |
440 |
> 22:07 < pipacs> ok, it seems to be fine |
441 |
> 22:07 < pappy-> fguard does the same for frame pointer |
442 |
> 22:07 < pappy-> pipacs: so it's a gcc bug |
443 |
> 22:07 < pappy-> *sigh* |
444 |
> 22:07 < pappy-> sorry about that |
445 |
> 22:07 < pipacs> on google i saw references to hard_frame_ptr_rtx |
446 |
> 22:07 < pappy-> i should've checked that more carefully |
447 |
> 22:07 < pipacs> maybe that's what you need? |
448 |
> 22:07 < pappy-> pipacs: i will check for it |
449 |
> 22:07 < pappy-> the problem was that the whole testing was done on amd |
450 |
> 22:07 < pappy-> also the gdb testing |
451 |
> 22:07 < pipacs> or just check how gcc itself defines __builtin_return_address |
452 |
> 22:07 < pappy-> where i compared the stack frames before-after |
453 |
> 22:08 < pipacs> gcc -m32 and you get i386 asm ;) |
454 |
> 22:09 < pappy-> pipacs: doing gcc -m32 on the amd64 machine yields the same problem |
455 |
> 22:09 < pappy-> -4 is missing |
456 |
> 22:09 < pappy-> nevermind |
457 |
> 22:09 < pappy-> how do you like the concept |
458 |
> 22:09 < pappy-> as you saw it working on amd64 now at least |
459 |
> 22:10 < pipacs> like it as in? |
460 |
> 22:10 < pappy-> do you think it delivers more than SSP |
461 |
> 22:10 < pipacs> what was the threat model that you're protecting against but ssp doesn't? |
462 |
> 22:11 < pappy-> well ssp doesn't protect against attacks where the control data can be written to directly |
463 |
> 22:11 < pappy-> using a formatstring or a write-after-read attack on the stack |
464 |
> 22:11 < pappy-> because ssp is putting a canary on the stack |
465 |
> 22:11 < pappy-> which can be read, then written to |
466 |
> 22:11 < pipacs> ah sure, it's a definitive improvment against those attacks |
467 |
> 22:12 < pappy-> so how would you rate it in conjunction with PaX |
468 |
> 22:12 < pipacs> it's not comparable, like ssp or anything that comes from the 'bug prevention' angle |
469 |
> 22:12 < pipacs> pax comes from the 'exploit technique prevention' angle |
470 |
> 22:13 < pipacs> imagine it as a two dimensional matrix, rows are exploit techniques, columns are bugs classes |
471 |
> 22:13 < pipacs> ssp & co cover columns |
472 |
> 22:13 < pipacs> pax & co cover rows |
473 |
> 22:13 < pappy-> well i know that |
474 |
> 22:13 < pipacs> obviously there's some overlap, i.e. they prevent exploiting certain bugs by certain exploit techniques |
475 |
> 22:14 < pappy-> well, i wanted your opinion on the encoded control data |
476 |
> 22:14 < pipacs> the rest differs in ways you can't compare, i mean, you can't just put a number behind them and say a > b |
477 |
> 22:14 < pappy-> would it be worth to use that for making it harder to do information leaking about ASLR? |
478 |
> 22:15 < pappy-> i don't want you to say: PaX is better... |
479 |
> 22:15 < pipacs> well, you encode 2 particular pointers on the stack |
480 |
> 22:15 < pipacs> but usually there're many more |
481 |
> 22:15 < pappy-> i just like to know if it's a good measure |
482 |
> 22:15 < pappy-> pipacs: i know, that's another thing |
483 |
> 22:15 < pappy-> my model is good if the program does not use function pointers |
484 |
> 22:15 < pappy-> which are a good starting point for an attack |
485 |
> 22:16 < pappy-> but as i previously said: |
486 |
> 22:16 < pappy-> the frames are always there |
487 |
> 22:16 < pipacs> i'd say encoding the saved EIP is more useful than encoding the saved frame ptr |
488 |
> 22:16 < pappy-> which implies it makes good friendly target for attackers |
489 |
> 22:16 < pipacs> because code ptrs come (mostly) from function calls only |
490 |
> 22:16 < pappy-> pipacs: frame pointer gives information leak about stack randomization |
491 |
> 22:16 < pipacs> so you're effectively encoding all of them on the stack |
492 |
> 22:16 < pipacs> however there're usually many stack-related ptrs on the stack |
493 |
> 22:16 < pipacs> addresses of local variables |
494 |
> 22:17 < pappy-> hrm |
495 |
> 22:17 < pipacs> tehrefore hiding saved ebp is less useful since the entropy in the stack ptr can be recovered from the other ptrs |
496 |
> 22:17 < pappy-> okay so it would make sense to go with EIP encoding |
497 |
> 22:17 < pipacs> see what i mean? |
498 |
> 22:17 < pappy-> and skip frame pointer altogether |
499 |
> 22:17 < pappy-> i'd live with that because it makes the SSXP patch very easier |
500 |
> 22:17 < pappy-> much clumsy stuff can go (like frame pointer enforced) |
501 |
> 22:17 < pipacs> well, that or extend it to all ptrs spilled on the stack, or at least those ptrs for which you can prove that they are stack related |
502 |
> 22:17 < pappy-> pipacs: yeah, thanks for the heads up |
503 |
> 22:17 < pipacs> which would get you quite close to what pointguard purported to be |
504 |
> 22:18 < pappy-> pipacs: i want to keep it inexpensive in terms of prologue and epilogue runtime |
505 |
> 22:18 < pappy-> with respect to PaX randomization being hidden as good as possible |
506 |
> 22:18 < pappy-> so people reading the stack cannot easily learn about addresses |
507 |
> 22:18 < pipacs> also, you can use the randomness in esp itself (under pax/execshield/2.6.1x) |
508 |
> 22:19 < pipacs> although that'd leak if one can read the stack |
509 |
> 22:19 < pipacs> which you say you assume in your threat model |
510 |
> 22:19 < pappy-> yes |
511 |
> 22:19 < pappy-> i assume full stack read and write after the read |
512 |
> 22:19 < pipacs> in that case though, the guard should not be spilled on the stack either |
513 |
> 22:20 < pappy-> how do you mean that? |
514 |
> 22:20 < pipacs> it should be read and kept in a register, never written to the stack |
515 |
> 22:20 < pipacs> -8(ebp) holds your guard, right? |
516 |
> 22:20 < pappy-> there is three guards |
517 |
> 22:20 < pappy-> pipacs: did you read the paper? |
518 |
> 22:20 < pipacs> ah, we're not at the end of it ;) |
519 |
> 22:20 < pipacs> not all of it, apparently |
520 |
> 22:20 < pappy-> you have been a very lazy boy |
521 |
> 22:20 < pappy-> shame on you |
522 |
> 22:20 < pappy-> for being so unprepared |
523 |
> 22:20 < pipacs> but what you showed so far, it used one guard to encode 2 ptrs, and that one guard was spilled on the stack |
524 |
> 22:20 < pappy-> no |
525 |
> 22:20 < pappy-> no no |
526 |
> 22:21 < pipacs> <pappy-> 15 movq %fs:40, %rax |
527 |
> 22:21 < pipacs> <pappy-> 16 movq %rax, -8(%rbp) |
528 |
> 22:21 < pappy-> http://dev.gentoo.org/~pappy/ssxp/latex2html/node85.html |
529 |
> 22:21 < pipacs> what's taht do then? |
530 |
> 22:21 < pappy-> look this please |
531 |
> 22:21 < pappy-> i showed and explained the level1 |
532 |
> 22:21 < pappy-> which does saved frame ptr xor retaddr xor guard -> canary |
533 |
> 22:21 < pappy-> and then level2 encoding is transforming the cleartext values of saved frame pointer and retaddr |
534 |
> 22:22 < pappy-> 23 movq %rax, -8(%rbp) |
535 |
> 22:22 < pappy-> 24 movq __stack_chk_fguard(%rip), %rax |
536 |
> 22:22 < pappy-> 25 xorq 0(%rbp), %rax |
537 |
> 22:22 < pappy-> 26 movq %rax, 0(%rbp) |
538 |
> 22:22 < pipacs> ok |
539 |
> 22:22 < pappy-> this is the level2 encoding of the saved frame pointer |
540 |
> 22:22 < pappy-> it is using a different guard |
541 |
> 22:22 < pappy-> for the reason you said |
542 |
> 22:22 < pappy-> spilling the guard on the stack is not an option if the original data is still there |
543 |
> 22:23 < pappy-> because then you just unroll the operations |
544 |
> 22:23 < pappy-> 27 movq __stack_chk_rguard(%rip), %rax |
545 |
> 22:23 < pappy-> 28 xorq 8(%rbp), %rax |
546 |
> 22:23 < pappy-> 29 movq %rax, 8(%rbp) |
547 |
> 22:23 < pipacs> i see one potential attack though |
548 |
> 22:23 < pappy-> which is |
549 |
> 22:23 < pipacs> if i can read enough stack, i may be able to read more than frame |
550 |
> 22:23 < pipacs> and i'd get then two pairs of encoded values w/ rguard/fguard |
551 |
> 22:24 < pappy-> how do you mean that |
552 |
> 22:24 < pipacs> xoring them together would get rid of rguard/fguard and leave the xor of two more or less related (predictable by the attacker) frame and eip values |
553 |
> 22:24 < pipacs> i have ebp1 ^ fguard, and ebp2 ^ fguard |
554 |
> 22:24 < pappy-> okay |
555 |
> 22:24 < pipacs> xor them together (as i leaked enough stack) |
556 |
> 22:24 < pappy-> sure |
557 |
> 22:25 < pipacs> i get ebp1 ^ ebp2 |
558 |
> 22:25 < pappy-> yes |
559 |
> 22:25 < pipacs> which reveals some info about ebp itself |
560 |
> 22:25 < pappy-> i know |
561 |
> 22:25 < pipacs> hmm, maybe nothing useful though |
562 |
> 22:25 < pappy-> but what can you do with that |
563 |
> 22:25 < pipacs> as the high bits are likely 0 |
564 |
> 22:25 < pipacs> let's take eip instead |
565 |
> 22:25 < pappy-> k |
566 |
> 22:25 < pipacs> so i could learn eip1 ^ eip2 |
567 |
> 22:26 < pipacs> and i'd know a priori where they're supposed be (since i can know the control flow chain at that point based on the src/user input) |
568 |
> 22:26 < pappy-> yes |
569 |
> 22:26 < pipacs> that'd reveal info about library addresses or their relative distance at least |
570 |
> 22:26 < pappy-> but randomization |
571 |
> 22:27 < pipacs> not so much useful under pax though as all libs are shifted by the same amount |
572 |
> 22:27 < pipacs> so again, the high bits would be 0 or some otehr constant |
573 |
> 22:27 < pipacs> anyway, just an idea, i don't immediately see much else 'wrong' with this scheme |
574 |
> 22:27 < pappy-> yes but can you take the info from eip1 ^ eip2 to form an address that can be used for an attack? |
575 |
> 22:27 < pappy-> with a reasonable probability not to miss? |
576 |
> 22:28 < pipacs> pappy, probably not to directly predict an address |
577 |
> 22:28 < pipacs> but maybe reduce the 'guess space' |
578 |
> 22:28 < pappy-> i know |
579 |
> 22:28 < pipacs> it'd need more thinking ;) |
580 |
> 22:28 < pappy-> but reducing the guess space wont give you a chance with grsec locking you out after 15 segfaults |
581 |
> 22:28 < pipacs> tell mayhem about it, im sure he won't hesitate ;P |
582 |
> 22:28 < pappy-> you can always be lucky |
583 |
> 22:28 < pappy-> but i would give you the win if you're lucky |
584 |
> 22:28 < pappy-> whois mayhem |
585 |
> 22:29 < pipacs> the guy who critized you the other day ;) |
586 |
> 22:29 < voidptr> the anti-pax! |
587 |
> 22:29 < pappy-> pipacs: so you would suggest i fix the obvious x86 errors with the generated assembler, throw away the frame pointer encoding |
588 |
> 22:29 < pappy-> the guy who critizised me? |
589 |
> 22:30 < pappy-> btw, where is pbusser |
590 |
> 22:30 < pipacs> well, considering that you assume stack leaking and that there're usually other stack related ptrs spilled on the stack, encoding ebp doesn't seem particularly useful |
591 |
> 22:30 < pappy-> pipacs: getting rid of frame pointer encoding was on my list nonetheless, because the patch sux because it enforces frame pointer |
592 |
> 22:31 < pappy-> and i'll make it more gentle when i only do work on the always existing eip |
593 |
> 22:31 < pappy-> without making speculations about ebp |
594 |
> 22:31 < pipacs> also, as a bonus exercise, you could try to identify function ptrs spilling on the stack |
595 |
> 22:31 < pappy-> you would never imagine how hard it is to find out in gcc source whether the currently constructed function (in gcc/function.c) is actually having a frame pointer at the moment or not |
596 |
> 22:31 < pipacs> and encode/decode them as needed |
597 |
> 22:32 < pipacs> that'd get you closer to pointguard and even beat it as you'd actually have working code, unlike them ;P |
598 |
> 22:32 < pappy-> yeah, harass me, i deserve it |
599 |
> 22:32 < pappy-> that bug with x86 makes me sad now |
600 |
> 22:32 < pappy-> i'm throwing my own party here with broken stuff |
601 |
> 22:33 < pappy-> pipacs: after the hardened toolchain migration work is done with gcc-4 and glibc-2.4 and glibc-2.5 i want to add this to hardened |
602 |
> 22:33 < pappy-> USE="ssxp" |
603 |
> 22:33 < pappy-> in the hardened toolchain |
604 |
> 22:33 < pappy-> together with PaX it's way to go to supercede normal SSP |
605 |
> 22:33 < pappy-> because it rocks the return address from being tampered with |
606 |
> 22:33 < pappy-> whcih is my main point of interest |
607 |
> 22:34 < pappy-> that valueable little precious item always in the same location makes up a good target for hijackers that recognize they can't do much with a nonexecutable stack |
608 |
> 22:34 < pappy-> and my personal belief is that SSXP blocks a bit of those |
609 |
> 22:34 < pappy-> at least the very simple ones |
610 |
> 22:34 < pappy-> which is a good start for me |
611 |
> 22:34 < pipacs> pappy, have you read the pax-future doc? |
612 |
> 22:34 < pappy-> pipacs: yeah |
613 |
> 22:34 < pipacs> in particular d.1 ? ;) |
614 |
> 22:35 < pipacs> see, i had plans for something similar as well |
615 |
> 22:35 < pappy-> i stole it |
616 |
> 22:35 < pipacs> something cheap but still somewhat useful |
617 |
> 22:35 < pappy-> to be honest. |
618 |
> 22:35 < pappy-> from your dea |
619 |
> 22:35 < pappy-> idea |
620 |
> 22:35 < pappy-> i was just faster :P |
621 |
> 22:35 < pipacs> although checking for function ptr derefences will be more powerful and useful |
622 |
> 22:35 < pipacs> hah |
623 |
> 22:35 < pipacs> i doubt i thought of it first |
624 |
> 22:35 < pipacs> since it's such a simple idea |
625 |
> 22:35 < pappy-> well, you planted the seed |
626 |
> 22:36 < pappy-> and i'm gracious i know you |
627 |
> 22:36 < pappy-> because without help of people like you people like me would never think of anything like that |
628 |
> 22:36 < pappy-> and that's what the community owes you |
629 |
> 22:36 < pappy-> you are making other people look good in front of the users |
630 |
> 22:36 < pappy-> because we learn much from your sexperience |
631 |
> 22:36 * pappy- laughs |
632 |
> 22:36 < pappy-> sorry bout the s |
633 |
> 22:36 < pappy-> *haha* |
634 |
> 22:36 < pappy-> <-- white and nerdy |
635 |
> 22:37 < pappy-> actually i am looking forward to pax-future.txt |
636 |
> 22:37 < pappy-> and i wonder when you will show the first pieces |
637 |
> 22:37 < pappy-> because it will be a milestone |
638 |
> 22:37 < pappy-> and hardened gentoo will love this stuff |
639 |
> 22:38 < pappy-> everybody is silent |
640 |
> 22:38 < pappy-> i thought this was going to be a meeting |
641 |
> 22:38 < pappy-> break the ice guys, i feel lonely |
642 |
> 22:39 < pappy-> i would like to know who of you guys read the paper |
643 |
> 22:39 < pappy-> i received lots of positive input on it |
644 |
> 22:39 < pappy-> what can i do to improve it? |
645 |
> 22:40 < pipacs> make it shorter maybe... ? :) |
646 |
> 22:40 < pappy-> *g* |
647 |
> 22:40 < pappy-> i was trying to get a professional version working |
648 |
> 22:40 < pappy-> without the novice explanations |
649 |
> 22:40 < pipacs> when i see 80+ pages for a paper... i tend not to be too motivated to read it from cover to cover ;P |
650 |
> 22:40 < pappy-> pipacs: well, there is a good index |
651 |
> 22:40 < pappy-> and you for example can skip chapter 1 and 2 completely |
652 |
> 22:40 < pappy-> because it deals with endianness, stack layout, etc |
653 |
> 22:41 < pappy-> i was trying to give a hands-on experience |
654 |
> 22:41 < voidptr> i only skipped through it |
655 |
> 22:41 < voidptr> sorry :) |
656 |
> 22:41 < pappy-> perhaps you are not the right audience for it- the people who loved it all didn't know what a stack pointer is |
657 |
> 22:41 < voidptr> and i liked the idea, from what i saw, and also now that you explained it here |
658 |
> 22:42 < pappy-> and for you guys it's probably really bloated |
659 |
> 22:42 < pappy-> voidptr: thanks for cheering me up :) |
660 |
> 22:42 < pappy-> phreak``: and you, how did you like the idea? |
661 |
> 22:42 < pappy-> phreak is my man at the hardened kernel pimping |
662 |
> 22:43 < pappy-> pipacs: thanks for your time, i appreciate it |
663 |
> 22:43 < phreak``> pappy-: have to read the backlog :) I was looking at 2.6.19 ;) |
664 |
> 22:43 < pappy-> pipacs: i can send the log around the world, can i? |
665 |
> 22:43 < pappy-> phreak``: *grrrr* |
666 |
> 22:43 < pipacs> oh shit, i forgot about that |
667 |
> 22:43 < pipacs> after *careful* editing, khm ;P |
668 |
> 22:44 < pappy-> "khm"? |
669 |
> 22:44 < pipacs> i hope i was all politically correct this time though ;) |
670 |
> 22:44 < voidptr> hah |
671 |
> 22:44 < pappy-> well, who gives a fck about political correctness |
672 |
> 22:44 < pappy-> now is the time to fuel some greasy jokes about selinux and fedora core |
673 |
> 22:44 < pappy-> give your best folks! |
674 |
> 22:44 < pipacs> you'll soon find out if you don't pay attention ;P |
675 |
> 22:44 < pappy-> it's still logging |
676 |
> 22:45 < pappy-> i will have to have a word with #gcc upon that frame pointer rtx thing |
677 |
> 22:45 < pappy-> it's hilarious |
678 |
> 22:45 < pappy-> on amd64 it uses the right offset |
679 |
> 22:45 < pappy-> on x86 it doesn't |
680 |
> 22:48 < pappy-> thanks to all of you for having the chat |
681 |
> 22:48 < pappy-> i would've brought some catering but irc is not very useful for that |
682 |
> 22:48 < voidptr> humm, now that i think about it again... i suppose most of the exploitable kernel bugs found would never be prevented by ssp, or even full bounds checking |
683 |
> 22:49 < voidptr> prevented/catched, whatever you want to call it :) |
684 |
> 22:49 < pappy-> voidptr: elaborate |
685 |
> 22:49 < voidptr> well lots of stuff found are logic mistakes |
686 |
> 22:51 < voidptr> well, lets say that environment sanitation on obsd, ld_preload etc that was recently published. |
687 |
> 22:51 < voidptr> it's just a bug, application/kernel logic |
688 |
> 22:51 < pappy-> These functions may be used to get information about the callers of a |
689 |
> 22:51 < pappy-> function. |
690 |
> 22:51 < pappy-> -- Built-in Function: void * __builtin_return_address (unsigned int |
691 |
> 22:51 < pappy-> LEVEL) |
692 |
> 22:52 < voidptr> an acl system would catch it, yes |
693 |
> 22:52 < pappy-> pipacs: do you think i can tinker with that in gcc/function.c ? |
694 |
> 22:52 < pappy-> pipacs: because when gcc/function.c runs, i don't think i can use it |
695 |
> 22:52 -!- benkoren [n=ben@65.162.43.173] has joined #ssxp |
696 |
> 22:52 < pappy-> because it would give the address of the function that's generating the object code |
697 |
> 22:52 < pappy-> benkoren: hi, i didnt forget you, sending you the log ASAP |
698 |
> 22:52 < benkoren> pappy-: i really appreciate that |
699 |
> 22:52 < pappy-> voidptr: well, nothing helps you from that |
700 |
> 22:52 < pappy-> voidptr: the world is free |
701 |
> 22:53 < pappy-> voidptr: we cannot protect everything everywhere |
702 |
> 22:53 < pappy-> because it would even contradict our own interests |
703 |
> 22:53 < pappy-> if everything was ultra secure |
704 |
> 22:53 < pappy-> you couldn't download something from the web |
705 |
> 22:53 < pappy-> or not talk to strangers on irc any more |
706 |
> 22:53 < pappy-> because it would all be restricted |
707 |
> 22:53 < pappy-> voidptr: the message is to make the difference between what you can do and what can't be done |
708 |
> 22:54 < pappy-> voidptr: which boils down to giving your users the advantage |
709 |
> 22:54 < pappy-> so that the pirates attack another ship |
710 |
> 22:54 < pappy-> not yours |
711 |
> 22:54 <@ssxp> if they want to sink it, they'll do nonetheless. |
712 |
> 22:54 < pappy-> whatever you do |
713 |
> 22:54 < voidptr> sure, but in case of ssp in kernel, what i heard was that it breaks stuff &/or has a notable performance hit |
714 |
> 22:54 < pappy-> you can ultrasecure your OS and everything around it |
715 |
> 22:55 < pappy-> if someone walks into your house with a gun, you are done |
716 |
> 22:55 < voidptr> so, if it has little benefit, i'd personally not use it :) |
717 |
> 22:55 < pappy-> voidptr: well, i guess SSP has no big chance to catch overflows in the kernel |
718 |
> 22:55 < pappy-> because that's kind of "out of the scope" |
719 |
> 22:55 < pappy-> there is buffer overflows every day |
720 |
> 22:56 < pappy-> just today, look at madwifi |
721 |
> 22:56 < pappy-> remote execution via network |
722 |
> 22:56 < pappy-> stack overflow in driver |
723 |
> 22:56 < voidptr> i see |
724 |
> 22:56 < pappy-> if it would have been compiled with SSP or something similar, it would probably have prevented that |
725 |
> 22:56 < pappy-> but if not, there is enough defense left |
726 |
> 22:56 < pappy-> like pax killing it or grsecurity containing it |
727 |
> 22:57 < voidptr> well what you would see is your X locking up? ;) |
728 |
> 22:57 < pappy-> voidptr: yeah, some kind of that way |
729 |
> 22:57 < voidptr> (and in that case i wouldn't be thankful pax saved me, but i would be annoyed :P) |
730 |
> 22:58 < voidptr> because i wouldn't know :) |
731 |
> 22:58 < pappy-> well that's a question of taste |
732 |
> 22:58 < voidptr> hehe :) |
733 |
> 22:58 < pappy-> i'd rather be protected and ceased |
734 |
> 22:58 < pappy-> rather than rooted and running |
735 |
> 22:58 < voidptr> of course :) |
736 |
> 22:58 < pappy-> http://user.noxa.de/~pappy/ssxp.log |
737 |
> 22:59 < benkoren> i have to say i've been running the hardened toolchain with X+KDE on top of it for about a week now and have had no such problems, not that there aren't elseware though |
738 |
> 22:59 < pappy-> benkoren: ping: http://user.noxa.de/~pappy/ssxp.log |
739 |
> 22:59 < benkoren> pappy-: thank you |
740 |
> 22:59 < pappy-> you'Re welcome |
741 |
> 22:59 < pappy-> codejunky: did you like it? |
742 |
> 23:00 < pappy-> i wonder where the blonde chicks have been, they said they'd come in the channel and show their boobs around |
743 |
> 23:01 < voidptr> i'm heading to bed, thanks and good luck |
744 |
> 23:01 < pappy-> yeah me too |
745 |
> 23:01 < pappy-> writing a test at school tomorrow |
746 |
> 23:02 < pappy-> pipacs: thanks again man for stopping by and making a fool out of me just for 4 bytes. |
747 |
> 23:02 < pappy-> pipacs: next time you just don't say anything :P |
748 |
> 23:02 * pappy- cuddles pipacs |
749 |
> 23:03 < pappy-> phreak``: i'm calling it a day |
750 |
> 23:03 < pappy-> guys, have fun and enjoy |
751 |
> 23:03 < pappy-> peace out! |