Q1
웹 문제인데 Super Super Guessing Chall.. 대충 요약하자면 QR Code Recovery + No Cookie Send Data + Command Injection + /etc/shadow + /etc/passwd + Login Account 이정도....
FLAG : h39dmxieYdne
Q2
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdint.h>
#include <sys/stat.h>
#include <fcntl.h>
int Solution(unsigned int *data)
{
if ( 316 * data[0]
- 901 * data[1]
+ 0 * data[2]
- 984 * data[3]
+ 359 * data[4]
- 986 * data[5]
- 869 * data[6]
- 733 * data[7]
- 800 * data[8]
+ 621 * data[9] == -347560 ){
if ( 754 * data[0]
+ 103 * data[1]
- 230 * data[2]
+ 359 * data[3]
- 516 * data[4]
+ 133 * data[5]
- 16 * data[6]
- 500 * data[7]
- 343 * data[8]
+ 980 * data[9] == 31039 ){
if ( 641 * data[0]
+262 * data[1]
- 415 * data[2]
- 889 * data[3]
+ 621 * data[4]
- 855 * data[5]
- 818 * data[6]
- 785 * data[7]
- 866 * data[8]
- 799 * data[9]== -262955 ){
if ( 473 * data[0]
- 57 * data[1]
- 477 * data[2]
+ 164 * data[3]
- 22 * data[4]
- 865 * data[5]
- 784 * data[6]
- 768 * data[7]
+ 416 * data[8]
- 121 * data[9]== -180990){
if ( 944 * data[0]
- 912 * data[1]
+ 667 * data[2]
+ 303 * data[3]
+ 524 * data[4]
- 523 * data[5]
+ 227 * data[6]
+ 799 * data[7]
- 618 * data[8]
- 739 * data[9]== 156060 ){
if ( 597 * data[0]
- 381 * data[1]
- 996 * data[2]
+ 109 * data[3]
+ 476 * data[4]
- 48 * data[5]
- 710 * data[6]
- 384 * data[7]
- 390 * data[8]
- 507 * data[9]== -143022){
if (164 * data[0]
- 300 * data[1]
- 808 * data[2]
+ 308 * data[3]
+ 311 * data[4]
- 144 * data[5]
+ 230 * data[6]
+ 251 * data[7]
+ 998 * data[8]
- 469 * data[9]== 18791){
if (301 * data[0]
+ 571 * data[1]
+ 955 * data[2]
- 462 * data[3]
- 4 * data[4]
- 541 * data[5]
- 380 * data[6]
+ 96 * data[7]
- 62 * data[8]
- 452 * data[9]== 60199){
if (703 * data[0]
- 635 * data[1]
- 733 * data[2]
+ 119 * data[3]
- 549 * data[4]
+ 220 * data[5]
+ 739 * data[6]
+ 102 * data[7]
+ 812 * data[8]
- 770 * data[9]== -48454){
if (207 * data[0]
+ 426 * data[1]
+ 324 * data[2]
+ 403 * data[3]
+ 149 * data[4]
+ 257 * data[5]
+ 765 * data[6]
- 368 * data[7]
+ 707 * data[8]
- 221 * data[9]== 202674 ){
return 1;
}
else
{
}
}
else
{
}
}
else
{
}
}
else
{
}
}
else
{
}
}
else
{
}
}
else
{
}
}
else
{
}
}
else
{
}
}
else
{
}
return 0;
}
int main(){
unsigned int data[10];
puts(" ** enjoy **");
fflush(stdin);
int i;
for (i = 0; i < sizeof(data)/sizeof(int); i++) {
printf(" Input[%d] : ", i);
fflush(stdin);
scanf("%u", &data[i]);
}
if ( (unsigned int)Solution(data) ) {
printf(" [+] flag {%c%c%c%c%c%c%c%c%c%c}\n", data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8], data[9]);
}
else {
puts(" [-] nope!!");
}
return 0;
}
Ez
from z3 import *
s = Solver()
data = [BitVec('a%i'%i,8)for i in range(10)]
s.add(( 316 * data[0]
- 901 * data[1]
+ 0 * data[2]
- 984 * data[3]
+ 359 * data[4]
- 986 * data[5]
- 869 * data[6]
- 733 * data[7]
- 800 * data[8]
+ 621 * data[9] == -347560 ))
s.add(( 754 * data[0]
+ 103 * data[1]
- 230 * data[2]
+ 359 * data[3]
- 516 * data[4]
+ 133 * data[5]
- 16 * data[6]
- 500 * data[7]
- 343 * data[8]
+ 980 * data[9] == 31039 ))
s.add(641 * data[0]
+262 * data[1]
- 415 * data[2]
- 889 * data[3]
+ 621 * data[4]
- 855 * data[5]
- 818 * data[6]
- 785 * data[7]
- 866 * data[8]
- 799 * data[9]== -262955)
s.add(( 473 * data[0]
- 57 * data[1]
- 477 * data[2]
+ 164 * data[3]
- 22 * data[4]
- 865 * data[5]
- 784 * data[6]
- 768 * data[7]
+ 416 * data[8]
- 121 * data[9]== -180990))
s.add(944 * data[0]
- 912 * data[1]
+ 667 * data[2]
+ 303 * data[3]
+ 524 * data[4]
- 523 * data[5]
+ 227 * data[6]
+ 799 * data[7]
- 618 * data[8]
- 739 * data[9]== 156060)
s.add(597 * data[0]
- 381 * data[1]
- 996 * data[2]
+ 109 * data[3]
+ 476 * data[4]
- 48 * data[5]
- 710 * data[6]
- 384 * data[7]
- 390 * data[8]
- 507 * data[9]== -143022)
s.add((164 * data[0]
- 300 * data[1]
- 808 * data[2]
+ 308 * data[3]
+ 311 * data[4]
- 144 * data[5]
+ 230 * data[6]
+ 251 * data[7]
+ 998 * data[8]
- 469 * data[9]== 18791))
s.add((301 * data[0]
+ 571 * data[1]
+ 955 * data[2]
- 462 * data[3]
- 4 * data[4]
- 541 * data[5]
- 380 * data[6]
+ 96 * data[7]
- 62 * data[8]
- 452 * data[9]== 60199))
s.add((703 * data[0]
- 635 * data[1]
- 733 * data[2]
+ 119 * data[3]
- 549 * data[4]
+ 220 * data[5]
+ 739 * data[6]
+ 102 * data[7]
+ 812 * data[8]
- 770 * data[9]== -48454))
s.add((207 * data[0]
+ 426 * data[1]
+ 324 * data[2]
+ 403 * data[3]
+ 149 * data[4]
+ 257 * data[5]
+ 765 * data[6]
- 368 * data[7]
+ 707 * data[8]
- 221 * data[9]== 202674 ))
print s.check()
m = s.model()
print m
print ''.join(chr(int(str(m.evaluate(data[i])))) for i in range(10))
FLAG : hello\0o0/
Q3
암호학 Diffie-Hellman 문제였다.
FLAG :
Q4
Chrome Extension 파일을 주는데 파일 추출하면 flag1.exe, flag2.exe, flag3.exe랑 암호화된 문자를 저장한 파일들이 나온다. python으로 만든 exe라 추출하려 했는데 실패했다.. 아쉬움
FLAG :
Q5
PPTX Format Problem? 아마.. 문제를 안봄 Guessing 같아서..
FLAG :
Q6
예선에서 나왔던 가위바위보 1000번 이기는 문제랑 유사하다.. WireShark Packet에서 ftp-data 추출하면 python exe가 나와서 추출하면 아래와 같이 나온다.
# Embedded file name: client.py
import Tkinter as tk
import tkMessageBox
import socket
from time import sleep
import threading
your_name = ''
opponent_name = ''
game_round = 0
game_timer = 4
your_choice = ''
opponent_choice = ''
TOTAL_NO_OF_ROUNDS = 1000
client = None
flag = None
window_main = tk.Tk()
window_main.title('Game Client')
serverFrame = tk.Frame(window_main)
lblHOST = tk.Label(serverFrame, text='Address:').pack(side=tk.LEFT)
entHost = tk.Entry(serverFrame)
entHost.pack(side=tk.LEFT)
lblPORT = tk.Label(serverFrame, text='Port:').pack(side=tk.LEFT)
entPort = tk.Entry(serverFrame)
entPort.pack(side=tk.LEFT)
serverFrame.pack(side=tk.TOP, pady=(5, 0))
top_welcome_frame = tk.Frame(window_main)
lbl_name = tk.Label(top_welcome_frame, text='Name:')
lbl_name.pack(side=tk.LEFT)
ent_name = tk.Entry(top_welcome_frame)
ent_name.pack(side=tk.LEFT)
btn_connect = tk.Button(top_welcome_frame, text='Connect', command=lambda : connect())
btn_connect.pack(side=tk.LEFT)
top_welcome_frame.pack(side=tk.TOP)
top_message_frame = tk.Frame(window_main)
lbl_line = tk.Label(top_message_frame, text='***********************************************************').pack()
lbl_welcome = tk.Label(top_message_frame, text='')
lbl_welcome.pack()
lbl_line_server = tk.Label(top_message_frame, text='***********************************************************')
lbl_line_server.pack_forget()
top_message_frame.pack(side=tk.TOP)
top_frame = tk.Frame(window_main)
top_left_frame = tk.Frame(top_frame, highlightbackground='green', highlightcolor='green', highlightthickness=1)
lbl_your_name = tk.Label(top_left_frame, text='Your name: ' + your_name, font='Helvetica 13 bold')
lbl_opponent_name = tk.Label(top_left_frame, text='Opponent: ' + opponent_name)
lbl_your_name.grid(row=0, column=0, padx=5, pady=8)
lbl_opponent_name.grid(row=1, column=0, padx=5, pady=8)
top_left_frame.pack(side=tk.LEFT, padx=(10, 10))
top_right_frame = tk.Frame(top_frame, highlightbackground='green', highlightcolor='green', highlightthickness=1)
lbl_game_round = tk.Label(top_right_frame, text='Game round (x) starts in', foreground='blue', font='Helvetica 14 bold')
lbl_timer = tk.Label(top_right_frame, text=' ', font='Helvetica 24 bold', foreground='blue')
lbl_game_round.grid(row=0, column=0, padx=5, pady=5)
lbl_timer.grid(row=1, column=0, padx=5, pady=5)
top_right_frame.pack(side=tk.RIGHT, padx=(10, 10))
top_frame.pack_forget()
middle_frame = tk.Frame(window_main)
lbl_line = tk.Label(middle_frame, text='***********************************************************').pack()
lbl_line = tk.Label(middle_frame, text='**** GAME LOG ****', font='Helvetica 13 bold', foreground='blue').pack()
lbl_line = tk.Label(middle_frame, text='***********************************************************').pack()
round_frame = tk.Frame(middle_frame)
lbl_round = tk.Label(round_frame, text='Round')
lbl_round.pack()
lbl_your_choice = tk.Label(round_frame, text='Your choice: None', font='Helvetica 13 bold')
lbl_your_choice.pack()
lbl_opponent_choice = tk.Label(round_frame, text='Opponent choice: ' + 'None')
lbl_opponent_choice.pack()
lbl_result = tk.Label(round_frame, text=' ', foreground='blue', font='Helvetica 14 bold')
lbl_result.pack()
round_frame.pack(side=tk.TOP)
final_frame = tk.Frame(middle_frame)
lbl_line = tk.Label(final_frame, text='***********************************************************').pack()
lbl_final_result = tk.Label(final_frame, text=' ', font='Helvetica 13 bold', foreground='blue')
lbl_final_result.pack()
lbl_line = tk.Label(final_frame, text='***********************************************************').pack()
final_frame.pack(side=tk.TOP)
middle_frame.pack_forget()
button_frame = tk.Frame(window_main)
photo_rock = tk.PhotoImage(file='rock.gif')
photo_paper = tk.PhotoImage(file='paper.gif')
photo_scissors = tk.PhotoImage(file='scissors.gif')
btn_rock = tk.Button(button_frame, text='Rock', command=lambda : choice('rock'), state=tk.DISABLED, image=photo_rock)
btn_paper = tk.Button(button_frame, text='Paper', command=lambda : choice('paper'), state=tk.DISABLED, image=photo_paper)
btn_scissors = tk.Button(button_frame, text='Scissors', command=lambda : choice('scissors'), state=tk.DISABLED, image=photo_scissors)
btn_rock.grid(row=0, column=0)
btn_paper.grid(row=0, column=1)
btn_scissors.grid(row=0, column=2)
button_frame.pack(side=tk.BOTTOM)
def game_logic(you, opponent):
winner = ''
rock = 'rock'
paper = 'paper'
scissors = 'scissors'
player0 = 'you'
player1 = 'opponent'
if you == opponent:
winner = 'draw'
elif you == rock:
if opponent == paper:
winner = player1
else:
winner = player0
elif you == scissors:
if opponent == rock:
winner = player1
else:
winner = player0
elif you == paper:
if opponent == scissors:
winner = player1
else:
winner = player0
return winner
def enable_disable_buttons(todo):
if todo == 'disable':
btn_rock.config(state=tk.DISABLED)
btn_paper.config(state=tk.DISABLED)
btn_scissors.config(state=tk.DISABLED)
else:
btn_rock.config(state=tk.NORMAL)
btn_paper.config(state=tk.NORMAL)
btn_scissors.config(state=tk.NORMAL)
def connect():
global HOST_ADDR
global your_name
global HOST_PORT
HOST_ADDR = entHost.get()
HOST_PORT = int(entPort.get())
if len(ent_name.get()) < 1:
tkMessageBox.showerror(title='ERROR!!!', message='You MUST enter your first name <e.g. John>')
else:
your_name = ent_name.get()
lbl_your_name['text'] = 'Your name: ' + your_name
connect_to_server(your_name, HOST_ADDR, HOST_PORT)
def count_down(my_timer, nothing):
global game_round
if game_round <= TOTAL_NO_OF_ROUNDS:
game_round = game_round + 1
lbl_game_round['text'] = 'Game round ' + str(game_round) + ' starts in'
while my_timer > 0:
my_timer = my_timer - 1
print 'game timer is: ' + str(my_timer)
lbl_timer['text'] = my_timer
sleep(1)
enable_disable_buttons('enable')
lbl_round['text'] = 'Round - ' + str(game_round)
lbl_final_result['text'] = ''
def choice(arg):
global opponent_choice
global flag
global client
global your_choice
global game_round
your_choice = arg
lbl_your_choice['text'] = 'Your choice: ' + your_choice
lbl_opponent_choice['text'] = 'Opponent choice: ' + opponent_choice
if client:
enable_disable_buttons('disable')
who_wins = game_logic(your_choice, opponent_choice)
if who_wins == 'you':
lbl_result['text'] = 'Result: WIN'
client.send('round$' + str(game_round))
if flag == None:
client.send('state$Yes')
else:
client.close()
elif who_wins == 'opponent':
game_round = 0
lbl_result['text'] = 'Result: LOSS'
lbl_final_result['text'] = 'Game Out'
lbl_final_result.config(foreground=color)
client.close()
else:
game_round = 0
lbl_result['text'] = 'Result: DRAW'
lbl_final_result['text'] = 'Game Out'
lbl_final_result.config(foreground=color)
client.close()
if game_round == TOTAL_NO_OF_ROUNDS:
final_result = ''
color = ''
enable_disable_buttons('disable')
game_round = 0
return
def connect_to_server(name, HOST_ADDR, HOST_PORT):
global client
try:
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((HOST_ADDR, HOST_PORT))
client.send(name)
btn_connect.config(state=tk.DISABLED)
ent_name.config(state=tk.DISABLED)
lbl_name.config(state=tk.DISABLED)
enable_disable_buttons('disable')
threading._start_new_thread(receive_message_from_server, (client, 'm'))
except Exception as e:
tkMessageBox.showerror(title='ERROR!!!', message='Cannot connect to host: ' + HOST_ADDR + ' on port: ' + str(HOST_PORT) + ' Server may be Unavailable. Try again later')
def receive_message_from_server(sck, m):
global opponent_choice
global opponent_name
global flag
while True:
from_server = sck.recv(4096)
if not from_server:
break
if from_server.startswith('welcome'):
if from_server == 'welcome':
lbl_welcome['text'] = 'Welcome ' + your_name
lbl_line_server.pack()
elif from_server.startswith('opponent_name$'):
opponent_name = from_server.replace('opponent_name$', '')
lbl_opponent_name['text'] = 'Opponent: ' + opponent_name
top_frame.pack()
middle_frame.pack()
if client:
client.send(str(game_round))
client.send('state$Yes')
lbl_welcome.config(state=tk.DISABLED)
lbl_line_server.config(state=tk.DISABLED)
elif from_server.startswith('$opponent_choice'):
opponent_choice = from_server.replace('$opponent_choice', '')
threading._start_new_thread(count_down, (game_timer, ''))
elif from_server.startswith('flag$'):
flag = from_server.replace('flag$', '')
lbl_final_result['text'] = 'flag={' + str(flag) + '}'
color = 'red'
lbl_final_result.config(foreground=color)
break
def on_closing():
if tkMessageBox.askokcancel('Quit', 'Do you want to quit?'):
if client:
try:
client.send('close$close')
window_main.destroy()
client.close()
except:
window_main.destroy()
else:
window_main.destroy()
window_main.protocol('WM_DELETE_WINDOW', on_closing)
window_main.mainloop()
문제가 조금 이상한게 guessing 요소가 너무 많다.. XOR까진 이해하겠는데 다음부터.. 모르겠다. 최대한 한 부분까지 넣었다.
from pwn import *
context.log_level = 'debug'
p = remote('192.168.10.25', 1231)
p.sendafter('Input the name=','Sung')
p.recv(4096)
sleep(2)
p.send('0')
# sleep(0.1)
p.send('state$Yes')
sleep(2)
p.recv(4096)
# p.send('flag$')
p.send('round$1000')
# p.send('state$Yes')
sleep(2)
#
p.recv(4096)
p.send('Hihisecure')
p.send('state$Yes')
sleep(2)
p.recv(4096)
p.send('round$1000')
# a = 'Hihisecure'
# b = 'Secretcode'
# p.sendafter('Input the Decryption=',';\x0ccretcode')
p.interactive()
# Secretcode=3b0c63726574636f6465
코드에 루틴도 없는데 ㅋㅋ.. Super Guessing! 결론은 못품 아무도.
FLAG :
Q7
Unity 문제인데 C# IL Patch해서 풀었다.
FLAG : gdiojcggemie
Q8
FLAG :
Q9
주요 메소드 기능을 통해서 설명해보겠습니다.
nklib 라이브러리를 불러옴
package com.example.ndklib;
public class NativeWrapper {
public native boolean nativeSum(boolean z, String str);
static {
System.loadLibrary("ndklib");
}
}
여기서 랜덤 값으로 대충 비교해서 맞추면 this.value1++ 해준다. 추가로 boolean a() 메소드가 존재하는데 이걸 이용해서 이따가 Hooking 하게 될 것이다.
public void winCheck(int i, int i2) {
int i3 = ((i + 3) - i2) % 3;
new javaBisic();
this.kk = a(this.value1);
if (i3 == 0) {
Toast makeText = Toast.makeText(getApplicationContext(), "비겼습니다, 아깝네요!!", 0);
this.myToast = makeText;
makeText.show();
} else if (i3 == 1) {
Toast makeText2 = Toast.makeText(getApplicationContext(), "이겼습니다. 점수 1점을 획득하셨습니다", 0);
this.myToast = makeText2;
this.value1++;
makeText2.show();
} else if (i3 == 2) {
this.myToast = Toast.makeText(getApplicationContext(), "졌습니다..다시 시도 해 주세요", 0);
System.out.println(this.kk);
this.myToast.show();
}
}
public boolean a(int i) {
return this.value1 > 10000;
}
아까 맞추면 this.value1이 계속 1씩 증가했는데 이걸 boolean a의 리턴이 True면 축하한다고 뜨면서 플래그를 제출 할 수 있게된다. 여기서 여기서 Library의 Native 함수를 이용해서 Edit에 입력한 문자를 인자로 넣어준다.
this.Check_Score.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
MainActivity mainActivity = MainActivity.this;
final boolean a = mainActivity.a(mainActivity.value1);
MainActivity.this.et = new EditText(MainActivity.this);
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setIcon((int) R.mipmap.ic_launcher);
if (a) {
builder.setIcon((int) R.mipmap.ic_launcher);
builder.setTitle((CharSequence) "Title");
builder.setMessage((CharSequence) "축하합니다!!!!!!\n관리자에게 플레그를 문의하세요!!");
builder.setView((View) MainActivity.this.et);
} else {
builder.setTitle((CharSequence) "Title");
builder.setMessage((CharSequence) "당신의 수는 " + MainActivity.this.value1 + "입니다 \n점수를 10000점 이상 받으시고, 관리자에게 플레그를 받으세요!!");
}
builder.setPositiveButton((CharSequence) "확인", (DialogInterface.OnClickListener) new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialogInterface, int i) {
MainActivity.this.aaa = nativeWrapper.nativeSum(a, MainActivity.this.et.getText().toString());
String str = MainActivity.this.aaa ? "축하드립니다!! 플레그를 제출 해 주세요" : "코드를 다시 확인 해 주세요";
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
AlertDialog.Builder title = builder.setTitle((CharSequence) MainActivity.this.et.getText().toString());
title.setMessage((CharSequence) str + "\n");
builder.create().show();
dialogInterface.dismiss();
}
});
builder.show();
}
});
그래서 nativeSum 함수를 보면 매우 복잡하게 되어있다.. 그래서 Native 함수도 후킹해서 strncmp가 호출되니까 v9을 후킹해서 값을 가져오면 된다.
unsigned __int64 __fastcall Java_com_example_ndklib_NativeWrapper_nativeSum(__int64 a1, __int64 a2, __int64 a3, __int64 a4)
{
__int64 v4; // r14
unsigned int v5; // er15
const char *v6; // rax
const char *v7; // r12
unsigned __int64 result; // rax
__int128 v9; // [rsp+0h] [rbp-58h]
char v10; // [rsp+10h] [rbp-48h]
char v11; // [rsp+11h] [rbp-47h]
char v12; // [rsp+12h] [rbp-46h]
char v13; // [rsp+13h] [rbp-45h]
char v14; // [rsp+14h] [rbp-44h]
char v15; // [rsp+15h] [rbp-43h]
char v16; // [rsp+16h] [rbp-42h]
char v17; // [rsp+17h] [rbp-41h]
char v18; // [rsp+18h] [rbp-40h]
unsigned __int64 v19; // [rsp+28h] [rbp-30h]
v4 = a4;
v19 = __readfsqword(0x28u);
v5 = 0;
v6 = (const char *)(*(__int64 (__fastcall **)(__int64, __int64, _QWORD))(*(_QWORD *)a1 + 1352LL))(a1, a4, 0LL);
v9 = xmmword_880;
*(__int128 *)((char *)&v9 + 10) = *(__int128 *)((char *)&xmmword_880 + 10);
LOBYTE(v9) = 102;
_mm_storeu_si128(
(__m128i *)((char *)&v9 + 1),
_mm_add_epi8(_mm_loadu_si128((const __m128i *)((char *)&v9 + 1)), (__m128i)xmmword_870));
v11 -= 17;
v13 -= 19;
v14 -= 20;
v15 -= 21;
v17 -= 23;
v18 -= 24;
v7 = v6;
BYTE9(v9) = BYTE1(v9) + 8;
BYTE14(v9) = BYTE4(v9) + 9;
v12 = BYTE2(v9) + 2;
BYTE11(v9) = BYTE2(v9) + 19;
BYTE12(v9) = BYTE5(v9) + 22;
HIBYTE(v9) = (BYTE1(v9) + 8) ^ BYTE5(v9);
v16 = BYTE7(v9) | BYTE5(v9);
BYTE8(v9) = (BYTE1(v9) + 8) | (BYTE2(v9) + 19);
v10 = 97;
if ( !strncmp(v6, (const char *)&v9, 0x19uLL) )
{
(*(void (__fastcall **)(__int64, __int64, const char *))(*(_QWORD *)a1 + 1360LL))(a1, v4, v7);
LOBYTE(v5) = 1;
}
result = __readfsqword(0x28u);
if ( result == v19 )
result = v5;
return result;
}
Frida Hookin 코드입니다. public boolean a() 함수의 리턴 값을 true로 변경해서 플래그를 입력할 수 있는 단계까지 간다. 그 다음에 native 함수를 이용해서 문자열 비교를 하니까 strncmp함수를 후킹해서 Memory.readByteArray()로 값을 긁어오면 된다.
Java.perform(function(){
console.log('START!');
var ptr = Java.use('com.example.ctf.MainActivity');
ptr.a.implementation = function(){
return true;
}
});
var nativeSum = Module.findExportByName(null,'Java_com_example_ndklib_NativeWrapper_nativeSum');
//Interceptor.attach(Module.findExportByName(null,'strncmp'),{
Interceptor.attach(Module.getExportByName('libndklib.so','strncmp'),{
onEnter: function(args){
console.log('strncmp args[2] : ' + args[2]);
console.log(Memory.readByteArray(ptr(parseInt(args[1])),0x20));
}
});
결과
FLAG : flag_A99ttEtW4h5a8c6ABy3E
Q10
Guessing zz;
FLAG : databaseencryption
후기
Super Guessing 대회지만 Q2, Q9 안드로이드 문제는 그렇게 Guessing은 아니라 재밌게 푼 거 같다. 너무 시행착오 많이 겪어서 시간 버려서 아쉬웠다. 굳굳
'CTF WriteUp' 카테고리의 다른 글
ASSEMBLY GAME (0) | 2021.06.05 |
---|---|
HSpace CTF Pengsu Wallet - Mobile (2) | 2021.05.11 |
제 14회 중고생정보보호올림피아드 본선 포너블 문제 풀이 (0) | 2020.10.14 |
2019 HCTF Writeup (0) | 2019.11.20 |
2019 제 14회 중고생정보보호올림피아드 풀이 (4) | 2019.09.23 |