Форум программистов, компьютерный форум, киберфорум
Наши страницы
PHP для начинающих
Войти
Регистрация
Восстановить пароль
Показать сообщение отдельно
Max Dark
шКодер самоучка
1970 / 1746 / 861
Регистрация: 09.10.2013
Сообщений: 3,855
Записей в блоге: 6
Завершенные тесты: 2
03.07.2016, 03:33 0

Задачка. Есть ли уязвимость

03.07.2016, 03:33. Просмотров 926. Ответов 14
Метки (Все метки)

Ответ

Не по теме:

Хех... а я почти весь код откоментировал... :-[

Кликните здесь для просмотра всего текста
PHP
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
<?php
header('Content-Type: text/html; charset=utf-8');
 
/**
 * Если $data === null - чтение значения из базы
 * иначе запись
 * Новые данные(включая обновления) добавляются в конец файла,
 * старые остаются на своих местах,
 * но ссылка на них теряется
 *
 * @param string $section
 * @param mixed $key
 * @param mixed|null $data
 * @return mixed
 */
function _d($section, $key, $data = null)
{
    if ($data !== null) {
        $data = serialize($data);
    }
    /**
     * дополняет файл блоком размера $size*strlen($c)
     * забивает данный блок значениями $c
     * 
     * @param int $size
     * @param string $c
     * @return integer старое значение размера файла
     */
    $gmem = function ($size, $c = "\0") use (&$f) {
        fseek($f, $ptr = fstat($f)['size']);
        fwrite($f, str_repeat($c, $size));
        fseek($f, $ptr);
        return $ptr;
    };
    /**
     * Если $data === null считывает с позиции $index и возвращает 32битное число
     * Иначе записывает в данную позицию $data, упакованную в последовательность чисел
     * 
     * @param integer $index
     * @param string|null $data
     * @return integer|null
     */
    $dword = function ($index, $data = null) use (&$f) {
        fseek($f, $index);
        if ($data === null) {
            return unpack('L', fread($f, 4))[1];
        }
        fwrite($f, pack("L", $data));
        fseek($f, $index);
        return null;
    };
    /**
     * Если $data === null считывает с позиции $index и возвращает строку символов
     * иначе записывает $data в формате размер+данные
     * Данные добавляются в конец файла
     *
     * @param integer $index
     * @param string|null $data
     * @return string
     */
    $buf = function ($index, $data = null) use (&$f, &$dword, &$buf, &$gmem) {
        fseek($f, $index);
        if ($data === null) {
            $size = $dword($index);
            fseek($f, $index + 4);
            return fread($f, $size);
        }
        $new = $gmem(4 + strlen($data));
        // запись длинны
        $dword($new, strlen($data));
        fseek($f, $new + 4);
        // запись данных
        fwrite($f, $data);
        return $new;
    };
    /**
     * Считывает запись по смещению $index
     *
     * @param integer $index
     * @return object
     */
    $rdata = function ($index) use (&$f, &$dword, &$buf) {
        return (object)[
            // ссылка на следующую запись
            'next' => $dword($index),
            // ID(?) записи
            // которое находятся по смещению,
            // которое(смещение ID) находится по смещению ($index + 4)
            'key' => $buf($dword($index + 4)),
            // собственно данные
            // которые находятся по смещению,
            // которое(смещение data) находится по смещению ($index + 8)
            'data' => $buf($dword($index + 8)),
            // смещение смещения ID
            'key_s' => $index + 4,
            // смещение смещения данных
            'data_s' => $index + 8,
        ];
    };
    // открываем базу данных
    $f = fopen(__DIR__ . "/" . md5($section) . ".kv", "c+");
    flock($f, LOCK_EX);
    // если размер базы меньше заданного, то значит, что база только что создана
    if (fstat($f)['size'] < (0xFFFF << 2)) {
        fseek($f, 0);
        // застолбить место нулями
        fwrite($f, str_repeat("\0", 0xFFFF << 2));
    }
    // получаем смещение из ключа(странное место... возможны одинаковые смещения при разных ключах)
    $_key = hexdec(substr(md5($key), 0, 4));
    $next = $dword($_key);
    while ($next) {
        $info = $rdata($next);
        if ($info->key === $key) {
            if ($data === null) {
                fclose($f);
                return @unserialize($info->data);
            }
            if ($info->data === $data) {
                goto _end;
            }
            // Обновление данных
            $dword($info->data_s, $buf(null, $data));
            goto _end;
        }
        $next = $info->next;
    }
    if ($data === null) {
        goto _end;
    }
 
    // добавление данных
    // добавляем участок для записи смещений
    $mem = $gmem(4 + 4 + 4);
    // запоминаем указатель на новый элемент
    $dword($_key, $mem);
    // запоминаем указатель на следующий
    $dword($mem + 4 * 0, $next);
    // записываем ID
    $key_ptr = $buf(null, $key);
    // запоминаем указатель на смещение ID
    $dword($mem + 4 * 1, $key_ptr);
    // записываем данные
    $data_ptr = $buf(null, $data);
    // запоминаем указатель на смещение данных
    $dword($mem + 4 * 2, $data_ptr);
 
    _end:
    fclose($f);
    return null;
}
 
function au()
{
    if (@$login = $_REQUEST['login'] AND @$password = $_REQUEST['password']) {
 
        if (preg_match('~[^a-zа-я0-9]|(^.{1,3}$)|(^.{13,}$)~iu', trim($login))) {
            return "Логин содержит не допустимые символы или не верной длинны(можно от 4 до 12 смиволов)";
        }
        if (preg_match('~[^a-zа-я0-9]|(^.{1,3}$)|(^.{13,}$)~iu', trim($password))) {
            return "Пароль содержит не допустимые символы или не верной длинны(можно от 4 до 12 смиволов)";
        }
        $hash = md5($password . '20bolwmclvz');
 
        while (1) {
            // ищем пользователя по логину
            $userID = _d('users_by_login', $login);
            // если нет такого, то добавляем в базу
            if ($userID === null) {
                $userID = md5(
                    mt_rand(111111, 999999) . mt_rand(111111, 999999) .
                    mt_rand(111111, 999999) . mt_rand(111111, 999999)
                );
 
                _d('users_by_login', $login, $userID);
                _d('users', $userID, [
                    'login' => $login,
                    'password' => $hash,
                    'sess' => null
                ]);
                /*
                 * Тут мы возвращаемся к началу цикла.
                 * Видимо только для того, чтобы
                 * получить те же самые данные,
                 * что только что добавили
                 * */
                continue;
            } else {
                /*
                 * Честно, не понимаю,
                 * зачем здесь _повторный_ поиск
                 * _того_же_ пользователя
                 **/
                $userID = _d('users_by_login', $login);
                $info = _d('users', $userID);
                if ($info['password'] !== $hash) {
                    return "Пароль неверен";
                }
            }
            break;
        }
        $sess = md5(
            mt_rand(111111, 999999) . mt_rand(111111, 999999) .
            mt_rand(111111, 999999) . mt_rand(111111, 999999)
        );
        _d('users_sess', $sess, [$userID, time()]);
        setcookie('sid', $sess);
        $_COOKIE['sid'] = $sess;
        header('Location: ' . parse_url($_SERVER['REQUEST_URI'])['path']);
        exit;
        // exit перед return true - облом. Обидно.
        return true;
    }
}
 
function drawRG($error_text)
{
    ?>
    <form class="rg-form">
        <div><?= $error_text; ?></div>
        <label for="login">Введите логин:</label>
        <input id="login" value="<?= @$_REQUEST['login']; ?>" name="login"/>
        <label for="password">Введите пароль:</label>
        <input id="password" value="<?= @$_REQUEST['password']; ?>" name="password"/>
        <input name="au" type="submit"/>
    </form>
    <?php
}
 
while (1) {
    if (@$sid = $_COOKIE['sid']) {
        if ($info = _d('users_sess', $sid)) {
            $userID = $info[0];
            $login = _d('users', $userID)['login'];
            $f = fopen(__DIR__ . '/online.list', 'c+');
            flock($f, LOCK_EX);
            $online = @fread($f, fstat($f)['size']);
            $online = @unserialize($online);
            if (!$online) $online = [];
            $online[$userID] = time();
 
            $onlineLogins = [];
            foreach ($_ = $online as $userOnlineID => $ltime) {
                if (time() > $ltime + 60 * 4) {
                    unset($online[$userOnlineID]);
                    continue;
                }
                $onlineLogins[] = _d('users', $userOnlineID)['login'];
            }
 
            $online[$userID] = time();
 
            ftruncate($f, 0);
            fseek($f, 0);
            fwrite($f, serialize($online));
            fclose($f);
 
            $onlineLogins = array_flip($onlineLogins);
            unset($onlineLogins[$login]);
            $onlineLogins = array_flip($onlineLogins);
 
            $rs = sprintf("<div>Привет %s</div>", $login);
            $rs .= sprintf("<div>Пользователи онлайн: </div>", $login);
            $rs .= '<span>' . implode(',', $onlineLogins) . '</span>';
            echo $rs;
            break;
        }
    } else {
        $s = au();
        if ($s === true) {
            continue;
        }
        drawRG($s);
        break;
    }
}
?>
 
<style>
    * {
        box-sizing: border-box;
    }
 
    .rg-form {
        position: fixed;
        left: 50%;
        margin-left: -150px;
        top: 20%;
        width: 300px;
        border: 2px solid #AAA;
        border-radius: 10px;
        padding: 10px;
    }
 
    .rg-form * {
        width: 100%;
    }
 
    .rg-form div {
        color: #f33;
    }
 
    [name=au] {
        margin-top: 10px;
    }
</style>



Вернуться к обсуждению:
Задачка. Есть ли уязвимость
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
03.07.2016, 03:33
Готовые ответы и решения:

Уязвимость сайта
Всем привет! Сайт сделан на старой самописной CMS. На формуме сайта стали...

Проверка сайта на уязвимость
Скажите пожалуйста как можно проверить свой сайта на уязвимость, например на...

Уязвимость в коде убрать
Здравствуйте. Есть две SQL базы на одной висит форум на другой скрипт для...

Уязвимость веб сервиса
увидел в одной старой теме о том что на сайте были открыты рут пути...

Уязвимость php файла
Здравствуйте Уважаемые! Есть файл myfile.php, и в начале этого файла стоит...

14
Другие темы раздела
PHP 500 ошибка http://www.cyberforum.ru/php-beginners/thread1774813.html
Всем доброй ночи, выходит 500 ошибка. текст ощибки: PHP Notice: Undefined index: items in /home/mycare00/yenimulk.az/www/oc-includes/osclass/core/View.php function _next($key) { ...
PHP Данные в базу Здравствуйте. Я делаю запрос в БД и у меня данные в таком формате при utf8_general_ci Мне нужно чтобы вместо таких данных были нормально русские. Сам SQL. (shp_about) DB::insert('INSERT... http://www.cyberforum.ru/php-beginners/thread1774769.html
Php запрос к MYSQL полученные значения нужно передать скрипту javascript PHP
Доброго времени суток такая задача php запрос к MYSQL, полученные значения заносятся в переменные - работает нормально. А дальше не знаю как значения передать скрипту javascript, чтобы эти значения...
Сделать route.php как .htaccess PHP
При настройке возникла проблема изменить .htaccess RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule .* index.php на файл route.php ...
PHP предупреждение при изменении файла http://www.cyberforum.ru/php-beginners/thread1774657.html
здравствуйте. как следить за текстовым файлом и когда он будет изменён выдать предупреждение. звук с окошком сообщения о изменениях.
PHP Массив и путь к файлу Почему он ругается?Что не так? Разобрался, такая переменная просто уже была. подробнее
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru