// Name: srop.c
// Compile: gcc -o srop srop.c -fno-stack-protector -no-pie

#include <unistd.h>

int gadget() {
  asm("pop %rax;"
      "syscall;"
      "ret" );
}

int main()
{
  char buf[16];
  read(0, buf ,1024);
}

[그림 1-1]

bof 취약점이 존재하고 gadget 함수를 보면 sigreturn 시스템 콜을 호출할 수 있다.

sigreturn 시스템 콜을 이용해 레지스터 값을 조작하여 execve 함수를 실행시켜 보자

[그림 1-2]

pwntools에서 바이너리 내에 특정 코드를 검색하고, 해당 주소를 가져오는 기능을 제공합니다.

이를 통해 가젯의 주소를 알아냅니다.

[그림 1-3]
[그림 1-4]

ret 값으로 gadget을 넣고 rax 값을 15로 바꿔서 sigreturn 시스템 콜이 실행되게 만듭니다.

[그림 1-5]

rax 값이 0xf(15)이고 syscall 명령어를 수행하면 sigreturn 시스템 콜이 실행됩니다.

sigreturn 시스템 콜은 스택에 있는 값들을 레지스터에 넣는 동작을 합니다.

[그림 1-6]

40만큼 dummy가 있고 레지스터를 0x41(A)로 덮어보겠습니다.

[그림 1-7]

모든 레지스터 값이 0x414141...로 덮였습니다.

 

execve 시스템 콜을 호출하기에 앞서, sigcontext 구조체에 정의된 레지스터의 순서를 고려하여 스택에 값을 넣어야 하는데 매번 구조체를 확인하면서 스택에 값을 넣는 건 말이 안 됨... pwntools에서는 SROP 공격을 수월하게 할 수 있게끔 SigreturnFrame 클래스를 제공합니다.

[그림 1-8]

해당 바이너리는 입력을 한 번만 받기 때문에 read 함수를 syscall 해서 bss 영역에 /bin/sh 문자열을 적고 rsp 값을 bss로 옮겨 ret 값을 조작해 준다.

[그림 1-9]

성공

 

 

알게 된 점

1. pwntools에는 바이너리에 특정 코드를 검색하고, 주소를 가져오는 기능이 있다.

2. bss = elf.bss() -> bss 영역 주소를 리턴한다.

3. frame2.rsp = bss + 0x500 -> https://dreamhack.io/forum/qna/1830


 

 

'Dreamhack - pwnable' 카테고리의 다른 글

iofile_aaw  (0) 2023.03.27
send_sig  (0) 2023.03.15
rtld  (0) 2023.03.12
environ  (0) 2023.03.06
master_canary  (1) 2023.02.15