CTF study diary----buuctf pwn rip

Some 64-bit glibc payloads fail to call system functions

Original link

http://blog.eonew.cn/archives/958

When I was working on the question, I found out that some new 64-bit glibc will crash directly when calling the system function after controlling the program flow. After debugging, I finally found the problem.

Download the files used in the experiment, Baidu network disk: https://pan.baidu.com/s/1mEcCIzeYtDIo-xmHsM8AFA (extraction code: ycyx).

question

When doing 64-bit pwn questions, especially stack overflow, after controlling the program flow, I thought that the shell could be obtained by directly calling the system function, but what we often see is a crash:

Thread 2.1 "speedrun-002" received signal SIGSEGV, Segmentation fault.
[Switching to process 25578]
0x00007f134a9fc2f6 in do_system (line=0x7f134ab60e9a "/bin/sh") at ../sysdeps/posix/system.c:125
125 ../sysdeps/posix/system.c: No such file or directory.
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
─────────────────────────────────────────────────[ REGISTERS ]─────────────────────────────────────────────────
 RAX  0x7f134ab60e97 ◂— sub    eax, 0x622f0063 /* '-c' */
 RBX  0x0
 RCX  0x7f134ab60e9f ◂— jae    0x7f134ab60f09 /* 'sh' */
 RDX  0x0
 RDI  0x2
 RSI  0x7f134ad9a6a0 (intr) ◂— 0x0
 R8   0x7f134ad9a600 (quit) ◂— 0x0
 R9   0x10
 R10  0x8
 R11  0x246
 R12  0x7f134ab60e9a ◂— 0x68732f6e69622f /* '/bin/sh' */
 R13  0x7ffe3e3eb140 ◂— 0x1
 R14  0x0
 R15  0x0
 RBP  0x601ce1 ◂— 0x0
 RSP  0x601c81 ◂— 0x0
 RIP  0x7f134a9fc2f6 (do_system+1094) ◂— movaps xmmword ptr [rsp + 0x40], xmm0
──────────────────────────────────────────────────[ DISASM ]───────────────────────────────────────────────────
  0x7f134a9fc2f6 <do_system+1094>    movaps xmmword ptr [rsp + 0x40], xmm0
   0x7f134a9fc2fb <do_system+1099>    call   sigaction <0x7f134a9ec110>

0x7f134a9fc300 <do_system+1104> lea rsi, [rip + 0x39e2f9] <0x7f134ad9a600>
0x7f134a9fc307 <do_system+1111> xor edx, edx
0x7f134a9fc309 <do_system+1113> mov edi, 3
0x7f134a9fc30e <do_system+1118> call sigaction <0x7f134a9ec110>

0x7f134a9fc313 <do_system+1123> xor edx, edx
0x7f134a9fc315 <do_system+1125> mov rsi, rbp
0x7f134a9fc318 <do_system+1128> mov edi, 2
0x7f134a9fc31d <do_system+1133> call sigprocmask <0x7f134a9ec140>

0x7f134a9fc322 <do_system+1138> mov rax, qword ptr [rip + 0x39bb7f]
───────────────────────────────────────────────────[ STACK ]───────────────────────────────────────────────────
00:0000│ rsp 0x601c81 ◂— 0x0
01:0008│ 0x601c89 —▸ 0x7f134ab60e97 ◂— sub eax, 0x622f0063 /* ‘-c’ */
02:0010│ 0x601c91 ◂— 0x0

04:0020│ 0x601ca1 —▸ 0x7f134a9fc360 (cancel_handler) ◂— push rbx
05:0028│ 0x601ca9 —▸ 0x601c9d ◂— 0x4a9fc36000000000
06:0030│ 0x601cb1 ◂— 0x0

─────────────────────────────────────────────────[ BACKTRACE ]─────────────────────────────────────────────────
f 0 7f134a9fc2f6 do_system+1094
f 1 a
f 2 0
Program received signal SIGSEGV (fault address 0x0)

The program crashed directly.

reason

The main reason is that the value required by 0x4F2F6the movaps [rsp+198h+var_158], xmm0instruction rsp+198h+var_158is aligned 16byte(0x10), otherwise it will directly trigger an interrupt and crash.

.text:000000000004F2F1 movhps  xmm0, [rsp+198h+var_190]
.text:000000000004F2F6 movaps  [rsp+198h+var_158], xmm0 ; here
.text:000000000004F2FB call    sigaction

demo

Here I use a simple program to demonstrate the problem.

shell.c

// compiled: gcc -g -no-pie -Og shell.c -o shell
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main()
{
system("/bin/sh");
return 0;
}

After the program is compiled, it can run normally, but what we want is to make the program not run normally.

Next, we will directly .text:000000000004F2F6 movaps [rsp+198h+var_158], xmm0 ; hereset a breakpoint here, that is do_system+1094, and then run here.

LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
─────────────────────────────────────────────────[ REGISTERS ]─────────────────────────────────────────────────
 RAX  0x7ffff7b97e97 ◂— sub    eax, 0x622f0063 /* '-c' */
 RBX  0x0
 RCX  0x7ffff7b97e9f ◂— jae    0x7ffff7b97f09 /* 'sh' */
 RDX  0x0
 RDI  0x2
 RSI  0x7ffff7dd16a0 (intr) ◂— 0x0
 R8   0x7ffff7dd1600 (quit) ◂— 0x0
 R9   0x7ffff7dd0d80 (initial) ◂— 0x0
 R10  0x8
 R11  0x246
 R12  0x400594 ◂— 0x68732f6e69622f /* '/bin/sh' */
 R13  0x7fffffffdc60 ◂— 0x1
 R14  0x0
 R15  0x0
 RBP  0x7fffffffda40 ◂— 0x0
 RSP  0x7fffffffd9e0 ◂— 0x0
 RIP  0x7ffff7a332f6 (do_system+1094) ◂— movaps xmmword ptr [rsp + 0x40], xmm0
──────────────────────────────────────────────────[ DISASM ]───────────────────────────────────────────────────
  0x7ffff7a332f6 <do_system+1094>    movaps xmmword ptr [rsp + 0x40], xmm0
   0x7ffff7a332fb <do_system+1099>    call   sigaction <0x7ffff7a23110>

0x7ffff7a33300 <do_system+1104> lea rsi, [rip + 0x39e2f9] <0x7ffff7dd1600>
0x7ffff7a33307 <do_system+1111> xor edx, edx
0x7ffff7a33309 <do_system+1113> mov edi, 3
0x7ffff7a3330e <do_system+1118> call sigaction <0x7ffff7a23110>

0x7ffff7a33313 <do_system+1123> xor edx, edx
0x7ffff7a33315 <do_system+1125> mov rsi, rbp
0x7ffff7a33318 <do_system+1128> mov edi, 2
0x7ffff7a3331d <do_system+1133> call sigprocmask <0x7ffff7a23140>

0x7ffff7a33322 <do_system+1138> mov rax, qword ptr [rip + 0x39bb7f]
───────────────────────────────────────────────────[ STACK ]───────────────────────────────────────────────────
00:0000│ rsp 0x7fffffffd9e0 ◂— 0x0
01:0008│ 0x7fffffffd9e8 —▸ 0x7ffff7b97e97 ◂— sub eax, 0x622f0063 /* ‘-c’ /
02:0010│ 0x7fffffffd9f0 ◂— 0x0

04:0020│ 0x7fffffffda00 —▸ 0x7ffff7a33360 (cancel_handler) ◂— push rbx
05:0028│ 0x7fffffffda08 —▸ 0x7fffffffd9fc ◂— 0xf7a3336000000000
06:0030│ 0x7fffffffda10 —▸ 0x7ffff7ffe738 —▸ 0x7ffff7ffe710 —▸ 0x7ffff7ffa000 ◂— jg 0x7ffff7ffa047
07:0038│ 0x7fffffffda18 ◂— 0x0
─────────────────────────────────────────────────[ BACKTRACE ]─────────────────────────────────────────────────
f 0 7ffff7a332f6 do_system+1094
f 1 7ffff7a3344a system+10
f 2 4004f7 main+16
f 3 7ffff7a05b97 __libc_start_main+231
Breakpoint (0x7ffff7a32eb0+1094)

Then look at rsp + 0x40the value.

pwndbg> p/x $rsp+0x40
$1 = 0x7fffffffda20

It can be seen that the value at this time is aligned, so it can run normally. Let's try to add rsp1 to see if it will crash.

pwndbg> set $rsp=$rsp+1
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
─────────────────────────────────────────────────[ REGISTERS ]─────────────────────────────────────────────────
 RAX  0x7ffff7b97e97 ◂— sub    eax, 0x622f0063 /* '-c' */
 RBX  0x0
 RCX  0x7ffff7b97e9f ◂— jae    0x7ffff7b97f09 /* 'sh' */
 RDX  0x0
 RDI  0x2
 RSI  0x7ffff7dd16a0 (intr) ◂— 0x0
 R8   0x7ffff7dd1600 (quit) ◂— 0x0
 R9   0x7ffff7dd0d80 (initial) ◂— 0x0
 R10  0x8
 R11  0x246
 R12  0x400594 ◂— 0x68732f6e69622f /* '/bin/sh' */
 R13  0x7fffffffdc60 ◂— 0x1
 R14  0x0
 R15  0x0
 RBP  0x7fffffffda40 ◂— 0x0
*RSP  0x7fffffffd9e1 ◂— 0x9700000000000000
 RIP  0x7ffff7a332f6 (do_system+1094) ◂— movaps xmmword ptr [rsp + 0x40], xmm0
──────────────────────────────────────────────────[ DISASM ]───────────────────────────────────────────────────
  0x7ffff7a332f6 <do_system+1094>    movaps xmmword ptr [rsp + 0x40], xmm0
   0x7ffff7a332fb <do_system+1099>    call   sigaction <0x7ffff7a23110>

0x7ffff7a33300 <do_system+1104> lea rsi, [rip + 0x39e2f9] <0x7ffff7dd1600>
0x7ffff7a33307 <do_system+1111> xor edx, edx
0x7ffff7a33309 <do_system+1113> mov edi, 3
0x7ffff7a3330e <do_system+1118> call sigaction <0x7ffff7a23110>

0x7ffff7a33313 <do_system+1123> xor edx, edx
0x7ffff7a33315 <do_system+1125> mov rsi, rbp
0x7ffff7a33318 <do_system+1128> mov edi, 2
0x7ffff7a3331d <do_system+1133> call sigprocmask <0x7ffff7a23140>

0x7ffff7a33322 <do_system+1138> mov rax, qword ptr [rip + 0x39bb7f]
───────────────────────────────────────────────────[ STACK ]───────────────────────────────────────────────────
00:0000│ rsp 0x7fffffffd9e1 ◂— 0x9700000000000000
01:0008│ 0x7fffffffd9e9 ◂— 0x7ffff7b97e
02:0010│ 0x7fffffffd9f1 ◂— 0x0
03:0018│ 0x7fffffffd9f9 ◂— 0x6000000000000000
04:0020│ 0x7fffffffda01 ◂— 0xfc00007ffff7a333
05:0028│ 0x7fffffffda09 ◂— 0x3800007fffffffd9
06:0030│ 0x7fffffffda11 ◂— 0x7ffff7ffe7
07:0038│ 0x7fffffffda19 ◂— 0x100000000000000
─────────────────────────────────────────────────[ BACKTRACE ]─────────────────────────────────────────────────
f 0 7ffff7a332f6 do_system+1094
f 1 4004
f 2 9700000000000000
f 3 100007ffff7a05b
f 4 6800000000000000
f 5 7fffffffdc
f 6 e700000001000080
f 7 4004
f 8 a400000000000000
f 9 6b6cdf11464cf7
f 10 6000000000004004
Breakpoint *(0x7ffff7a32eb0+1094)

Continue to view rsp + 0x40the values.

pwndbg> p/x $rsp+0x40
$2 = 0x7fffffffda21

You can see that it is not aligned at this time, so continue to run.

pwndbg> c
Continuing.

Thread 2.1 “shell” received signal SIGSEGV, Segmentation fault.
0x00007ffff7a332f6 in do_system (line=0x400594 “/bin/sh”) at …/sysdeps/posix/system.c:125
125 in …/sysdeps/posix/system.c
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
─────────────────────────────────────────────────[ REGISTERS ]─────────────────────────────────────────────────
RAX 0x7ffff7b97e97 ◂— sub eax, 0x622f0063 /* ‘-c’ /
RBX 0x0
RCX 0x7ffff7b97e9f ◂— jae 0x7ffff7b97f09 / ‘sh’ /
RDX 0x0
RDI 0x2
RSI 0x7ffff7dd16a0 (intr) ◂— 0x0
R8 0x7ffff7dd1600 (quit) ◂— 0x0
R9 0x7ffff7dd0d80 (initial) ◂— 0x0
R10 0x8
R11 0x246
R12 0x400594 ◂— 0x68732f6e69622f / ‘/bin/sh’ */
R13 0x7fffffffdc60 ◂— 0x1
R14 0x0
R15 0x0
RBP 0x7fffffffda40 ◂— 0x0
RSP 0x7fffffffd9e1 ◂— 0x9700000000000000
RIP 0x7ffff7a332f6 (do_system+1094) ◂— movaps xmmword ptr [rsp + 0x40], xmm0
──────────────────────────────────────────────────[ DISASM ]───────────────────────────────────────────────────
0x7ffff7a332f6 <do_system+1094> movaps xmmword ptr [rsp + 0x40], xmm0
0x7ffff7a332fb <do_system+1099> call sigaction <0x7ffff7a23110>

0x7ffff7a33300 <do_system+1104> lea rsi, [rip + 0x39e2f9] <0x7ffff7dd1600>
0x7ffff7a33307 <do_system+1111> xor edx, edx
0x7ffff7a33309 <do_system+1113> mov edi, 3
0x7ffff7a3330e <do_system+1118> call sigaction <0x7ffff7a23110>

0x7ffff7a33313 <do_system+1123> xor edx, edx
0x7ffff7a33315 <do_system+1125> mov rsi, rbp
0x7ffff7a33318 <do_system+1128> mov edi, 2
0x7ffff7a3331d <do_system+1133> call sigprocmask <0x7ffff7a23140>

0x7ffff7a33322 <do_system+1138> mov rax, qword ptr [rip + 0x39bb7f]
───────────────────────────────────────────────────[ STACK ]───────────────────────────────────────────────────
00:0000│ rsp 0x7fffffffd9e1 ◂— 0x9700000000000000
01:0008│ 0x7fffffffd9e9 ◂— 0x7ffff7b97e
02:0010│ 0x7fffffffd9f1 ◂— 0x0
03:0018│ 0x7fffffffd9f9 ◂— 0x6000000000000000
04:0020│ 0x7fffffffda01 ◂— 0xfc00007ffff7a333
05:0028│ 0x7fffffffda09 ◂— 0x3800007fffffffd9
06:0030│ 0x7fffffffda11 ◂— 0x7ffff7ffe7
07:0038│ 0x7fffffffda19 ◂— 0x100000000000000
─────────────────────────────────────────────────[ BACKTRACE ]─────────────────────────────────────────────────
f 0 7ffff7a332f6 do_system+1094
f 1 4004
f 2 9700000000000000
f 3 100007ffff7a05b
f 4 6800000000000000
f 5 7fffffffdc
f 6 e700000001000080
f 7 4004
f 8 a400000000000000
f 9 6b6cdf11464cf7
f 10 6000000000004004
Program received signal SIGSEGV (fault address 0x0)

As you can see from the above, the program crashes directly.

Solution

The core idea is to change the address of the stack.

  1. Change payload length
  2. stack transfer

Change payload length

Directly change the length of our payload. When the stack overflows, the address of the stack will naturally be different. Then, +1if the address of the stack does not work, it will continue to increase. If it is changed 16 times at most, the stack will definitely be aligned.

stack transfer

When the payload has a length limit, we can try to transfer the stack to change the stack address. If there is no alignment, continue to change the stack address +1until the stack is aligned.

call execve

The execve function is used to replace the system function, and this requirement is even higher, because it needs three parameters to be called normally. That is to say, we need to construct rdi, rsi, rdxthese three parameters.

int execve(const char * filename,char * const argv[ ],char * const envp[ ]);

Summarize

If you encounter problems, start debugging more.

Guess you like

Origin blog.csdn.net/weixin_44411509/article/details/109860791