어셈블리어에서 셀코드(OpCode)로 변환 후 제출은 어떻게 하나요?

밑에 다른 게시글도 보고 어셈에서 OpCode로 변환하는 방법 찾아서 테스트 삼아 Hello world!!!\n를 출력하는 셀코드를 전송하였는데 아무 반응이 없습니다.

아래는 쉘 코드에 적용된 어셈블리로 작성된 코드 입니다.

  • 주석은 이해를 돕기 위해 md 파일에만 작성되어 있으며 실제 코드에서는 주석이 없습니다.
	.globl main
	.type	main, @function
	.intel_syntax noprefix

main:
	push	rbp
	mov	rbp, rsp
	mov	rax, 0xa212121646c726f  ; 스택에 hello world!!!\n 저장중
	push	rax                 ; 스택에 hello world!!!\n 저장중
	mov	rax, 0x77202c6f6c6c6548 ; 스택에 hello world!!!\n 저장중
	push	rax                 ; 스택에 hello world!!!\n 저장중
	xor	rax, rax                ; rax = 0
	xor	rdx, rdx                ; rdx = 0
	mov	al, 0x1                 ; al(rax) = 1 ; write
	mov	rdi, rax                ; rdi = rax(1) ; stdout
	lea	rsi, [rsp]              ; rsi = 스택에 저장된 hello world!!!\n 주소
	mov	dl, 0x10                ; rsi = 16 ; 출력할 글자 수
	syscall                     ; write(stdout, 스택에 저장된 hello world!!!\n 주소, 16)
	xor	rax, rax                ; rax = 0 ; return 0
	leave
	ret

해당 코드 작성 이후 gcc a.s -o a.out 커맨드를 통하여 어셈블리어를 컴파일하였고 ./a.out 커맨드 실행 결과로 Hello, world!!!\n이 나왔습니다.

이후 objdump -d a.out 커맨드로 OpCode를 확인하였고 이를 쉘 코드로 변경하였습니다.
아래는 objdump -d a.out 커맨드 출력 결과입니다.

...다른 코드들
00000000000005fa <main>:
 5fa:	55                   	push   %rbp
 5fb:	48 89 e5             	mov    %rsp,%rbp
 5fe:	48 b8 6f 72 6c 64 21 	movabs $0xa212121646c726f,%rax
 605:	21 21 0a
 608:	50                   	push   %rax
 609:	48 b8 48 65 6c 6c 6f 	movabs $0x77202c6f6c6c6548,%rax
 610:	2c 20 77
 613:	50                   	push   %rax
 614:	48 31 c0             	xor    %rax,%rax
 617:	48 31 d2             	xor    %rdx,%rdx
 61a:	b0 01                	mov    $0x1,%al
 61c:	48 89 c7             	mov    %rax,%rdi
 61f:	48 8d 34 24          	lea    (%rsp),%rsi
 623:	b2 10                	mov    $0x10,%dl
 625:	0f 05                	syscall
 627:	48 31 c0             	xor    %rax,%rax
 62a:	c9                   	leaveq
 62b:	c3                   	retq
 62c:	0f 1f 40 00          	nopl   0x0(%rax)
...다른 코드들

아래는 위 결과를 셀 코드(OpCode)로 변환한 결과입니다.

\x55\x48\x89\xe5\x48\xb8\x6f\x72\x6c\x64\x21\x21\x21\x0a\x50\x48\xb8\x48\x65\x6c\x6c\x6f\x2c\x20\x77\x50\x48\x31\xc0\x48\x31\xd2\xb0\x01\x48\x89\xc7\x48\x8d\x34\x24\xb2\x10\x0f\x05\x48\x31\xc0\xc9\xc3\x0f\x1f\x40\x00

이후 해당 셀 코드가 정상 작동하는지 C 코드를 통해 확인 후 nc host1.dreamhack.games <custom port> 커맨드를 통해 제출하였는데 하다못해 에러 메세지조차도 없으며 아무런 반응이 없습니다.

아래는 C 코드를 통한 확인 및 제가 진행한 제출 과정입니다.

  • 아래 코드에서는 shellcode: 이후 엔터가 들어간 것처럼 보이나 실제로는 한줄로 구성되어 있으며 길이가 길어 엔터가 들어간 것처럼 보이는 것입니다.
root@dev:~/dh# cat a.c
char s[] = "\x55\x48\x89\xe5\x48\xb8\x6f\x72\x6c\x64\x21\x21\x21\x0a\x50\x48\xb8\x48\x65\x6c\x6c\x6f\x2c\x20\x77\x50\x48\x31\xc0\x48\x31\xd2\xb0\x01\x48\x89\xc7\x48\x8d\x34\x24\xb2\x10\x0f\x05\x48\x31\xc0\xc9\xc3\x0f\x1f\x40\x00";

int main(void) {
	(*(void (*)()) s)();
}
root@dev:~/dh# gcc -fno-stack-protector -z execstack -o shell.out a.c
root@dev:~/dh# ./shell.out
Hello, world!!!
root@dev:~/dh# nc host1.dreamhack.games <some port>
shellcode: \x55\x48\x89\xe5\x48\xb8\x6f\x72\x6c\x64\x21\x21\x21\x0a\x50\x48\xb8\x48\x65\x6c\x6c\x6f\x2c\x20\x77\x50\x48\x31\xc0\x48\x31\xd2\xb0\x01\x48\x89\xc7\x48\x8d\x34\x24\xb2\x10\x0f\x05\x48\x31\xc0\xc9\xc3\x0f\x1f\x40\x00
root@dev:~/dh#

어떻게 제출해야지 인식이 될까요...

#pwnable
작성자 정보
답변 1
avatar
김진우
대표 업적 없음

\x55\x48\x89\xe5\x48\xb8\x6f\x72\x6c\x64\x21\x21\x21\x0a\x50\x48\xb8\x48\x65\x6c\x6c\x6f\x2c\x20\x77\x50\x48\x31\xc0\x48\x31\xd2\xb0\x01\x48\x89\xc7\x48\x8d\x34\x24\xb2\x10\x0f\x05\x48\x31\xc0\xc9\xc3\x0f\x1f\x40\x00를 그대로 제출하시면 문자열로 제출됩니다.

그러니까 \x55가 opcode 55가 아닌 그냥 문자열 '\x55'로 인식되게 되요...

파이썬 pwntools를 이용해서

from pwn import *

p = remote('host1.dreamhack.games',<port>)

shellcode = b'\x55\x48\x89\xe5\x48\xb8\x6f\x72\x6c\x64\x21\x21\x21\x0a\x50\x48\xb8\x48\x65\x6c\x6c\x6f\x2c\x20\x77\x50\x48\x31\xc0\x48\x31\xd2\xb0\x01\x48\x89\xc7\x48\x8d\x34\x24\xb2\x10\x0f\x05\x48\x31\xc0\xc9\xc3\x0f\x1f\x40\x00'
  
p.send(shellcode)
  
p.interactive()

이런식으로 제출하실 수 있습니다.

2022.02.13. 20:24
질문에 대한 답을 알고 계신가요?
지식을 나누고 포인트를 획득해보세요.
답변하고 포인트 받기